// Copyright (c) Microsoft Corporation
// All rights reserved. 
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED ON AN  *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//
// See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.

// TODO: Verify that this is is still needed..
#define NTDDI_VERSION 0x06010000

#include <v8.h>
#include "nan.h"
#include <string>
#include <ppltasks.h>
#include "CollectionsConverter.h"
#include "CollectionsWrap.h"
#include "node-async.h"
#include "NodeRtUtils.h"
#include "OpaqueWrapper.h"
#include "WrapperBase.h"

#using <Windows.WinMD>

// this undefs fixes the issues of compiling Windows.Data.Json, Windows.Storag.FileProperties, and Windows.Stroage.Search
// Some of the node header files brings windows definitions with the same names as some of the WinRT methods
#undef DocumentProperties
#undef GetObject
#undef CreateEvent
#undef FindText
#undef SendMessage

const char* REGISTRATION_TOKEN_MAP_PROPERTY_NAME = "__registrationTokenMap__";

using v8::Array;
using v8::String;
using v8::Handle;
using v8::Value;
using v8::Boolean;
using v8::Integer;
using v8::FunctionTemplate;
using v8::Object;
using v8::Local;
using v8::Function;
using v8::Date;
using v8::Number;
using v8::PropertyAttribute;
using v8::Primitive;
using Nan::HandleScope;
using Nan::Persistent;
using Nan::Undefined;
using Nan::True;
using Nan::False;
using Nan::Null;
using Nan::MaybeLocal;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::TryCatch;
using namespace concurrency;

namespace NodeRT { namespace Windows { namespace Globalization { namespace NumberFormatting { 

  v8::Local<v8::Value> WrapINumberRounder(::Windows::Globalization::NumberFormatting::INumberRounder^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::INumberRounder^ UnwrapINumberRounder(Local<Value> value);
  
  v8::Local<v8::Value> WrapSignificantDigitsNumberRounder(::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ UnwrapSignificantDigitsNumberRounder(Local<Value> value);
  
  v8::Local<v8::Value> WrapIncrementNumberRounder(::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ UnwrapIncrementNumberRounder(Local<Value> value);
  
  v8::Local<v8::Value> WrapINumberFormatter(::Windows::Globalization::NumberFormatting::INumberFormatter^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::INumberFormatter^ UnwrapINumberFormatter(Local<Value> value);
  
  v8::Local<v8::Value> WrapINumberFormatter2(::Windows::Globalization::NumberFormatting::INumberFormatter2^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::INumberFormatter2^ UnwrapINumberFormatter2(Local<Value> value);
  
  v8::Local<v8::Value> WrapINumberParser(::Windows::Globalization::NumberFormatting::INumberParser^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::INumberParser^ UnwrapINumberParser(Local<Value> value);
  
  v8::Local<v8::Value> WrapINumberFormatterOptions(::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ UnwrapINumberFormatterOptions(Local<Value> value);
  
  v8::Local<v8::Value> WrapISignificantDigitsOption(::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ UnwrapISignificantDigitsOption(Local<Value> value);
  
  v8::Local<v8::Value> WrapINumberRounderOption(::Windows::Globalization::NumberFormatting::INumberRounderOption^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::INumberRounderOption^ UnwrapINumberRounderOption(Local<Value> value);
  
  v8::Local<v8::Value> WrapISignedZeroOption(::Windows::Globalization::NumberFormatting::ISignedZeroOption^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::ISignedZeroOption^ UnwrapISignedZeroOption(Local<Value> value);
  
  v8::Local<v8::Value> WrapDecimalFormatter(::Windows::Globalization::NumberFormatting::DecimalFormatter^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::DecimalFormatter^ UnwrapDecimalFormatter(Local<Value> value);
  
  v8::Local<v8::Value> WrapPercentFormatter(::Windows::Globalization::NumberFormatting::PercentFormatter^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::PercentFormatter^ UnwrapPercentFormatter(Local<Value> value);
  
  v8::Local<v8::Value> WrapPermilleFormatter(::Windows::Globalization::NumberFormatting::PermilleFormatter^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::PermilleFormatter^ UnwrapPermilleFormatter(Local<Value> value);
  
  v8::Local<v8::Value> WrapCurrencyFormatter(::Windows::Globalization::NumberFormatting::CurrencyFormatter^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::CurrencyFormatter^ UnwrapCurrencyFormatter(Local<Value> value);
  
  v8::Local<v8::Value> WrapNumeralSystemTranslator(::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ wintRtInstance);
  ::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ UnwrapNumeralSystemTranslator(Local<Value> value);
  


  static void InitRoundingAlgorithmEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("RoundingAlgorithm").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("none").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::None)));
	Nan::Set(enumObject, Nan::New<String>("roundDown").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundDown)));
	Nan::Set(enumObject, Nan::New<String>("roundUp").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundUp)));
	Nan::Set(enumObject, Nan::New<String>("roundTowardsZero").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundTowardsZero)));
	Nan::Set(enumObject, Nan::New<String>("roundAwayFromZero").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundAwayFromZero)));
	Nan::Set(enumObject, Nan::New<String>("roundHalfDown").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundHalfDown)));
	Nan::Set(enumObject, Nan::New<String>("roundHalfUp").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundHalfUp)));
	Nan::Set(enumObject, Nan::New<String>("roundHalfTowardsZero").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundHalfTowardsZero)));
	Nan::Set(enumObject, Nan::New<String>("roundHalfAwayFromZero").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundHalfAwayFromZero)));
	Nan::Set(enumObject, Nan::New<String>("roundHalfToEven").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundHalfToEven)));
	Nan::Set(enumObject, Nan::New<String>("roundHalfToOdd").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::RoundingAlgorithm::RoundHalfToOdd)));
  }


  static void InitCurrencyFormatterModeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("CurrencyFormatterMode").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("useSymbol").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::CurrencyFormatterMode::UseSymbol)));
	Nan::Set(enumObject, Nan::New<String>("useCurrencyCode").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Globalization::NumberFormatting::CurrencyFormatterMode::UseCurrencyCode)));
  }



  
  class INumberRounder : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("INumberRounder").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "roundInt32", RoundInt32);
      Nan::SetPrototypeMethod(localRef, "roundUInt32", RoundUInt32);
      Nan::SetPrototypeMethod(localRef, "roundInt64", RoundInt64);
      Nan::SetPrototypeMethod(localRef, "roundUInt64", RoundUInt64);
      Nan::SetPrototypeMethod(localRef, "roundSingle", RoundSingle);
      Nan::SetPrototypeMethod(localRef, "roundDouble", RoundDouble);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INumberRounder").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INumberRounder(::Windows::Globalization::NumberFormatting::INumberRounder^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::INumberRounder^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::INumberRounder^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      INumberRounder *wrapperInstance = new INumberRounder(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::INumberRounder^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::INumberRounder^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINumberRounder(winRtInstance));
    }


  
    static void RoundInt32(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info.This()))
      {
        return;
      }

      INumberRounder *wrapper = INumberRounder::Unwrap<INumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          int arg0 = static_cast<int>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          int result;
          result = wrapper->_instance->RoundInt32(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundUInt32(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info.This()))
      {
        return;
      }

      INumberRounder *wrapper = INumberRounder::Unwrap<INumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          
          unsigned int result;
          result = wrapper->_instance->RoundUInt32(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundInt64(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info.This()))
      {
        return;
      }

      INumberRounder *wrapper = INumberRounder::Unwrap<INumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          __int64 result;
          result = wrapper->_instance->RoundInt64(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundUInt64(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info.This()))
      {
        return;
      }

      INumberRounder *wrapper = INumberRounder::Unwrap<INumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          unsigned __int64 result;
          result = wrapper->_instance->RoundUInt64(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundSingle(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info.This()))
      {
        return;
      }

      INumberRounder *wrapper = INumberRounder::Unwrap<INumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          float arg0 = static_cast<float>(Nan::To<double>(info[0]).FromMaybe(0.0));
          
          float result;
          result = wrapper->_instance->RoundSingle(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(info.This()))
      {
        return;
      }

      INumberRounder *wrapper = INumberRounder::Unwrap<INumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          double result;
          result = wrapper->_instance->RoundDouble(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }





  private:
    ::Windows::Globalization::NumberFormatting::INumberRounder^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINumberRounder(::Windows::Globalization::NumberFormatting::INumberRounder^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::INumberRounder^ UnwrapINumberRounder(Local<Value> value);
  };
  Persistent<FunctionTemplate> INumberRounder::s_constructorTemplate;

  v8::Local<v8::Value> WrapINumberRounder(::Windows::Globalization::NumberFormatting::INumberRounder^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(INumberRounder::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::INumberRounder^ UnwrapINumberRounder(Local<Value> value)
  {
     return INumberRounder::Unwrap<INumberRounder>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINumberRounder(Local<Object> exports)
  {
    INumberRounder::Init(exports);
  }

  class SignificantDigitsNumberRounder : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("SignificantDigitsNumberRounder").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "roundInt32", RoundInt32);
      Nan::SetPrototypeMethod(localRef, "roundUInt32", RoundUInt32);
      Nan::SetPrototypeMethod(localRef, "roundInt64", RoundInt64);
      Nan::SetPrototypeMethod(localRef, "roundUInt64", RoundUInt64);
      Nan::SetPrototypeMethod(localRef, "roundSingle", RoundSingle);
      Nan::SetPrototypeMethod(localRef, "roundDouble", RoundDouble);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("significantDigits").ToLocalChecked(), SignificantDigitsGetter, SignificantDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("roundingAlgorithm").ToLocalChecked(), RoundingAlgorithmGetter, RoundingAlgorithmSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("SignificantDigitsNumberRounder").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    SignificantDigitsNumberRounder(::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      SignificantDigitsNumberRounder *wrapperInstance = new SignificantDigitsNumberRounder(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapSignificantDigitsNumberRounder(winRtInstance));
    }


  
    static void RoundInt32(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          int arg0 = static_cast<int>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          int result;
          result = wrapper->_instance->RoundInt32(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundUInt32(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          
          unsigned int result;
          result = wrapper->_instance->RoundUInt32(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundInt64(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          __int64 result;
          result = wrapper->_instance->RoundInt64(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundUInt64(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          unsigned __int64 result;
          result = wrapper->_instance->RoundUInt64(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundSingle(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          float arg0 = static_cast<float>(Nan::To<double>(info[0]).FromMaybe(0.0));
          
          float result;
          result = wrapper->_instance->RoundSingle(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          double result;
          result = wrapper->_instance->RoundDouble(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    static void SignificantDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->SignificantDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SignificantDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsUint32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      try 
      {
        
        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->SignificantDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void RoundingAlgorithmGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::RoundingAlgorithm result = wrapper->_instance->RoundingAlgorithm;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void RoundingAlgorithmSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^>(info.This()))
      {
        return;
      }

      SignificantDigitsNumberRounder *wrapper = SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::RoundingAlgorithm winRtValue = static_cast<::Windows::Globalization::NumberFormatting::RoundingAlgorithm>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->RoundingAlgorithm = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapSignificantDigitsNumberRounder(::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ UnwrapSignificantDigitsNumberRounder(Local<Value> value);
  };
  Persistent<FunctionTemplate> SignificantDigitsNumberRounder::s_constructorTemplate;

  v8::Local<v8::Value> WrapSignificantDigitsNumberRounder(::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(SignificantDigitsNumberRounder::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::SignificantDigitsNumberRounder^ UnwrapSignificantDigitsNumberRounder(Local<Value> value)
  {
     return SignificantDigitsNumberRounder::Unwrap<SignificantDigitsNumberRounder>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitSignificantDigitsNumberRounder(Local<Object> exports)
  {
    SignificantDigitsNumberRounder::Init(exports);
  }

  class IncrementNumberRounder : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("IncrementNumberRounder").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "roundInt32", RoundInt32);
      Nan::SetPrototypeMethod(localRef, "roundUInt32", RoundUInt32);
      Nan::SetPrototypeMethod(localRef, "roundInt64", RoundInt64);
      Nan::SetPrototypeMethod(localRef, "roundUInt64", RoundUInt64);
      Nan::SetPrototypeMethod(localRef, "roundSingle", RoundSingle);
      Nan::SetPrototypeMethod(localRef, "roundDouble", RoundDouble);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("roundingAlgorithm").ToLocalChecked(), RoundingAlgorithmGetter, RoundingAlgorithmSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("increment").ToLocalChecked(), IncrementGetter, IncrementSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IncrementNumberRounder").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IncrementNumberRounder(::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::IncrementNumberRounder^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::IncrementNumberRounder();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      IncrementNumberRounder *wrapperInstance = new IncrementNumberRounder(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::IncrementNumberRounder^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIncrementNumberRounder(winRtInstance));
    }


  
    static void RoundInt32(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          int arg0 = static_cast<int>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          int result;
          result = wrapper->_instance->RoundInt32(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundUInt32(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          
          unsigned int result;
          result = wrapper->_instance->RoundUInt32(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundInt64(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          __int64 result;
          result = wrapper->_instance->RoundInt64(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundUInt64(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          unsigned __int64 result;
          result = wrapper->_instance->RoundUInt64(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundSingle(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          float arg0 = static_cast<float>(Nan::To<double>(info[0]).FromMaybe(0.0));
          
          float result;
          result = wrapper->_instance->RoundSingle(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void RoundDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          double result;
          result = wrapper->_instance->RoundDouble(arg0);
          info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    static void RoundingAlgorithmGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::RoundingAlgorithm result = wrapper->_instance->RoundingAlgorithm;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void RoundingAlgorithmSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::RoundingAlgorithm winRtValue = static_cast<::Windows::Globalization::NumberFormatting::RoundingAlgorithm>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->RoundingAlgorithm = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IncrementGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      try 
      {
        double result = wrapper->_instance->Increment;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IncrementSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsNumber())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::IncrementNumberRounder^>(info.This()))
      {
        return;
      }

      IncrementNumberRounder *wrapper = IncrementNumberRounder::Unwrap<IncrementNumberRounder>(info.This());

      try 
      {
        
        double winRtValue = Nan::To<double>(value).FromMaybe(0.0);

        wrapper->_instance->Increment = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIncrementNumberRounder(::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ UnwrapIncrementNumberRounder(Local<Value> value);
  };
  Persistent<FunctionTemplate> IncrementNumberRounder::s_constructorTemplate;

  v8::Local<v8::Value> WrapIncrementNumberRounder(::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(IncrementNumberRounder::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::IncrementNumberRounder^ UnwrapIncrementNumberRounder(Local<Value> value)
  {
     return IncrementNumberRounder::Unwrap<IncrementNumberRounder>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIncrementNumberRounder(Local<Object> exports)
  {
    IncrementNumberRounder::Init(exports);
  }

  class INumberFormatter : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("INumberFormatter").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "format", Format);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INumberFormatter").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INumberFormatter(::Windows::Globalization::NumberFormatting::INumberFormatter^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::INumberFormatter^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::INumberFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      INumberFormatter *wrapperInstance = new INumberFormatter(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::INumberFormatter^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::INumberFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINumberFormatter(winRtInstance));
    }


  
    static void Format(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter^>(info.This()))
      {
        return;
      }

      INumberFormatter *wrapper = INumberFormatter::Unwrap<INumberFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }





  private:
    ::Windows::Globalization::NumberFormatting::INumberFormatter^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINumberFormatter(::Windows::Globalization::NumberFormatting::INumberFormatter^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::INumberFormatter^ UnwrapINumberFormatter(Local<Value> value);
  };
  Persistent<FunctionTemplate> INumberFormatter::s_constructorTemplate;

  v8::Local<v8::Value> WrapINumberFormatter(::Windows::Globalization::NumberFormatting::INumberFormatter^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(INumberFormatter::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::INumberFormatter^ UnwrapINumberFormatter(Local<Value> value)
  {
     return INumberFormatter::Unwrap<INumberFormatter>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINumberFormatter(Local<Object> exports)
  {
    INumberFormatter::Init(exports);
  }

  class INumberFormatter2 : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("INumberFormatter2").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "formatInt", FormatInt);
      Nan::SetPrototypeMethod(localRef, "formatUInt", FormatUInt);
      Nan::SetPrototypeMethod(localRef, "formatDouble", FormatDouble);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INumberFormatter2").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INumberFormatter2(::Windows::Globalization::NumberFormatting::INumberFormatter2^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::INumberFormatter2^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter2^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::INumberFormatter2^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      INumberFormatter2 *wrapperInstance = new INumberFormatter2(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter2^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::INumberFormatter2^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::INumberFormatter2^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINumberFormatter2(winRtInstance));
    }


  
    static void FormatInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter2^>(info.This()))
      {
        return;
      }

      INumberFormatter2 *wrapper = INumberFormatter2::Unwrap<INumberFormatter2>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter2^>(info.This()))
      {
        return;
      }

      INumberFormatter2 *wrapper = INumberFormatter2::Unwrap<INumberFormatter2>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->FormatUInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatter2^>(info.This()))
      {
        return;
      }

      INumberFormatter2 *wrapper = INumberFormatter2::Unwrap<INumberFormatter2>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatDouble(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }





  private:
    ::Windows::Globalization::NumberFormatting::INumberFormatter2^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINumberFormatter2(::Windows::Globalization::NumberFormatting::INumberFormatter2^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::INumberFormatter2^ UnwrapINumberFormatter2(Local<Value> value);
  };
  Persistent<FunctionTemplate> INumberFormatter2::s_constructorTemplate;

  v8::Local<v8::Value> WrapINumberFormatter2(::Windows::Globalization::NumberFormatting::INumberFormatter2^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(INumberFormatter2::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::INumberFormatter2^ UnwrapINumberFormatter2(Local<Value> value)
  {
     return INumberFormatter2::Unwrap<INumberFormatter2>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINumberFormatter2(Local<Object> exports)
  {
    INumberFormatter2::Init(exports);
  }

  class INumberParser : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("INumberParser").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "parseInt", ParseInt);
      Nan::SetPrototypeMethod(localRef, "parseUInt", ParseUInt);
      Nan::SetPrototypeMethod(localRef, "parseDouble", ParseDouble);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INumberParser").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INumberParser(::Windows::Globalization::NumberFormatting::INumberParser^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::INumberParser^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberParser^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::INumberParser^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      INumberParser *wrapperInstance = new INumberParser(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberParser^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::INumberParser^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::INumberParser^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINumberParser(winRtInstance));
    }


  
    static void ParseInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberParser^>(info.This()))
      {
        return;
      }

      INumberParser *wrapper = INumberParser::Unwrap<INumberParser>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<__int64>^ result;
          result = wrapper->_instance->ParseInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberParser^>(info.This()))
      {
        return;
      }

      INumberParser *wrapper = INumberParser::Unwrap<INumberParser>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<unsigned __int64>^ result;
          result = wrapper->_instance->ParseUInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberParser^>(info.This()))
      {
        return;
      }

      INumberParser *wrapper = INumberParser::Unwrap<INumberParser>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<double>^ result;
          result = wrapper->_instance->ParseDouble(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }





  private:
    ::Windows::Globalization::NumberFormatting::INumberParser^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINumberParser(::Windows::Globalization::NumberFormatting::INumberParser^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::INumberParser^ UnwrapINumberParser(Local<Value> value);
  };
  Persistent<FunctionTemplate> INumberParser::s_constructorTemplate;

  v8::Local<v8::Value> WrapINumberParser(::Windows::Globalization::NumberFormatting::INumberParser^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(INumberParser::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::INumberParser^ UnwrapINumberParser(Local<Value> value)
  {
     return INumberParser::Unwrap<INumberParser>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINumberParser(Local<Object> exports)
  {
    INumberParser::Init(exports);
  }

  class INumberFormatterOptions : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("INumberFormatterOptions").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("fractionDigits").ToLocalChecked(), FractionDigitsGetter, FractionDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("geographicRegion").ToLocalChecked(), GeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("integerDigits").ToLocalChecked(), IntegerDigitsGetter, IntegerDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isDecimalPointAlwaysDisplayed").ToLocalChecked(), IsDecimalPointAlwaysDisplayedGetter, IsDecimalPointAlwaysDisplayedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isGrouped").ToLocalChecked(), IsGroupedGetter, IsGroupedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("languages").ToLocalChecked(), LanguagesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numeralSystem").ToLocalChecked(), NumeralSystemGetter, NumeralSystemSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedGeographicRegion").ToLocalChecked(), ResolvedGeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedLanguage").ToLocalChecked(), ResolvedLanguageGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INumberFormatterOptions").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INumberFormatterOptions(::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::INumberFormatterOptions^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      INumberFormatterOptions *wrapperInstance = new INumberFormatterOptions(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::INumberFormatterOptions^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINumberFormatterOptions(winRtInstance));
    }


  



    static void FractionDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        int result = wrapper->_instance->FractionDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FractionDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->FractionDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void GeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->GeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IntegerDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        int result = wrapper->_instance->IntegerDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IntegerDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->IntegerDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsDecimalPointAlwaysDisplayedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsDecimalPointAlwaysDisplayed;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsDecimalPointAlwaysDisplayedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsDecimalPointAlwaysDisplayed = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsGroupedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsGrouped;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsGroupedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsGrouped = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void LanguagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->Languages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Platform::String^>::CreateVectorViewWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumeralSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->NumeralSystem;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumeralSystemSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->NumeralSystem = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResolvedGeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedGeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedLanguageGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberFormatterOptions^>(info.This()))
      {
        return;
      }

      INumberFormatterOptions *wrapper = INumberFormatterOptions::Unwrap<INumberFormatterOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedLanguage;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINumberFormatterOptions(::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ UnwrapINumberFormatterOptions(Local<Value> value);
  };
  Persistent<FunctionTemplate> INumberFormatterOptions::s_constructorTemplate;

  v8::Local<v8::Value> WrapINumberFormatterOptions(::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(INumberFormatterOptions::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::INumberFormatterOptions^ UnwrapINumberFormatterOptions(Local<Value> value)
  {
     return INumberFormatterOptions::Unwrap<INumberFormatterOptions>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINumberFormatterOptions(Local<Object> exports)
  {
    INumberFormatterOptions::Init(exports);
  }

  class ISignificantDigitsOption : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("ISignificantDigitsOption").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("significantDigits").ToLocalChecked(), SignificantDigitsGetter, SignificantDigitsSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("ISignificantDigitsOption").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ISignificantDigitsOption(::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      ISignificantDigitsOption *wrapperInstance = new ISignificantDigitsOption(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapISignificantDigitsOption(winRtInstance));
    }


  



    static void SignificantDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^>(info.This()))
      {
        return;
      }

      ISignificantDigitsOption *wrapper = ISignificantDigitsOption::Unwrap<ISignificantDigitsOption>(info.This());

      try 
      {
        int result = wrapper->_instance->SignificantDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SignificantDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^>(info.This()))
      {
        return;
      }

      ISignificantDigitsOption *wrapper = ISignificantDigitsOption::Unwrap<ISignificantDigitsOption>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SignificantDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapISignificantDigitsOption(::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ UnwrapISignificantDigitsOption(Local<Value> value);
  };
  Persistent<FunctionTemplate> ISignificantDigitsOption::s_constructorTemplate;

  v8::Local<v8::Value> WrapISignificantDigitsOption(::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(ISignificantDigitsOption::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::ISignificantDigitsOption^ UnwrapISignificantDigitsOption(Local<Value> value)
  {
     return ISignificantDigitsOption::Unwrap<ISignificantDigitsOption>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitISignificantDigitsOption(Local<Object> exports)
  {
    ISignificantDigitsOption::Init(exports);
  }

  class INumberRounderOption : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("INumberRounderOption").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numberRounder").ToLocalChecked(), NumberRounderGetter, NumberRounderSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INumberRounderOption").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INumberRounderOption(::Windows::Globalization::NumberFormatting::INumberRounderOption^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::INumberRounderOption^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounderOption^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::INumberRounderOption^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      INumberRounderOption *wrapperInstance = new INumberRounderOption(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounderOption^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::INumberRounderOption^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::INumberRounderOption^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINumberRounderOption(winRtInstance));
    }


  



    static void NumberRounderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounderOption^>(info.This()))
      {
        return;
      }

      INumberRounderOption *wrapper = INumberRounderOption::Unwrap<INumberRounderOption>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::INumberRounder^ result = wrapper->_instance->NumberRounder;
        info.GetReturnValue().Set(WrapINumberRounder(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounderOption^>(info.This()))
      {
        return;
      }

      INumberRounderOption *wrapper = INumberRounderOption::Unwrap<INumberRounderOption>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::INumberRounder^ winRtValue = dynamic_cast<::Windows::Globalization::NumberFormatting::INumberRounder^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->NumberRounder = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::INumberRounderOption^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINumberRounderOption(::Windows::Globalization::NumberFormatting::INumberRounderOption^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::INumberRounderOption^ UnwrapINumberRounderOption(Local<Value> value);
  };
  Persistent<FunctionTemplate> INumberRounderOption::s_constructorTemplate;

  v8::Local<v8::Value> WrapINumberRounderOption(::Windows::Globalization::NumberFormatting::INumberRounderOption^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(INumberRounderOption::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::INumberRounderOption^ UnwrapINumberRounderOption(Local<Value> value)
  {
     return INumberRounderOption::Unwrap<INumberRounderOption>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINumberRounderOption(Local<Object> exports)
  {
    INumberRounderOption::Init(exports);
  }

  class ISignedZeroOption : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("ISignedZeroOption").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isZeroSigned").ToLocalChecked(), IsZeroSignedGetter, IsZeroSignedSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("ISignedZeroOption").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ISignedZeroOption(::Windows::Globalization::NumberFormatting::ISignedZeroOption^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::ISignedZeroOption^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignedZeroOption^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::ISignedZeroOption^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      ISignedZeroOption *wrapperInstance = new ISignedZeroOption(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignedZeroOption^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::ISignedZeroOption^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::ISignedZeroOption^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapISignedZeroOption(winRtInstance));
    }


  



    static void IsZeroSignedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignedZeroOption^>(info.This()))
      {
        return;
      }

      ISignedZeroOption *wrapper = ISignedZeroOption::Unwrap<ISignedZeroOption>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsZeroSigned;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsZeroSignedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::ISignedZeroOption^>(info.This()))
      {
        return;
      }

      ISignedZeroOption *wrapper = ISignedZeroOption::Unwrap<ISignedZeroOption>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsZeroSigned = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::ISignedZeroOption^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapISignedZeroOption(::Windows::Globalization::NumberFormatting::ISignedZeroOption^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::ISignedZeroOption^ UnwrapISignedZeroOption(Local<Value> value);
  };
  Persistent<FunctionTemplate> ISignedZeroOption::s_constructorTemplate;

  v8::Local<v8::Value> WrapISignedZeroOption(::Windows::Globalization::NumberFormatting::ISignedZeroOption^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(ISignedZeroOption::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::ISignedZeroOption^ UnwrapISignedZeroOption(Local<Value> value)
  {
     return ISignedZeroOption::Unwrap<ISignedZeroOption>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitISignedZeroOption(Local<Object> exports)
  {
    ISignedZeroOption::Init(exports);
  }

  class DecimalFormatter : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("DecimalFormatter").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "format", Format);
      Nan::SetPrototypeMethod(localRef, "formatInt", FormatInt);
      Nan::SetPrototypeMethod(localRef, "formatUInt", FormatUInt);
      Nan::SetPrototypeMethod(localRef, "formatDouble", FormatDouble);
      Nan::SetPrototypeMethod(localRef, "parseInt", ParseInt);
      Nan::SetPrototypeMethod(localRef, "parseUInt", ParseUInt);
      Nan::SetPrototypeMethod(localRef, "parseDouble", ParseDouble);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isDecimalPointAlwaysDisplayed").ToLocalChecked(), IsDecimalPointAlwaysDisplayedGetter, IsDecimalPointAlwaysDisplayedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("integerDigits").ToLocalChecked(), IntegerDigitsGetter, IntegerDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isGrouped").ToLocalChecked(), IsGroupedGetter, IsGroupedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("fractionDigits").ToLocalChecked(), FractionDigitsGetter, FractionDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numeralSystem").ToLocalChecked(), NumeralSystemGetter, NumeralSystemSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("geographicRegion").ToLocalChecked(), GeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("languages").ToLocalChecked(), LanguagesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedGeographicRegion").ToLocalChecked(), ResolvedGeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedLanguage").ToLocalChecked(), ResolvedLanguageGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numberRounder").ToLocalChecked(), NumberRounderGetter, NumberRounderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isZeroSigned").ToLocalChecked(), IsZeroSignedGetter, IsZeroSignedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("significantDigits").ToLocalChecked(), SignificantDigitsGetter, SignificantDigitsSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("DecimalFormatter").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    DecimalFormatter(::Windows::Globalization::NumberFormatting::DecimalFormatter^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::DecimalFormatter^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::DecimalFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(info[0]) || info[0]->IsArray())
        && info[1]->IsString())
      {
        try
        {
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Local<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::DecimalFormatter(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::DecimalFormatter();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      DecimalFormatter *wrapperInstance = new DecimalFormatter(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::DecimalFormatter^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::DecimalFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapDecimalFormatter(winRtInstance));
    }


  
    static void Format(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->FormatUInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatDouble(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<__int64>^ result;
          result = wrapper->_instance->ParseInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<unsigned __int64>^ result;
          result = wrapper->_instance->ParseUInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<double>^ result;
          result = wrapper->_instance->ParseDouble(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    static void IsDecimalPointAlwaysDisplayedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsDecimalPointAlwaysDisplayed;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsDecimalPointAlwaysDisplayedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsDecimalPointAlwaysDisplayed = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IntegerDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->IntegerDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IntegerDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->IntegerDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsGroupedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsGrouped;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsGroupedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsGrouped = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void FractionDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->FractionDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FractionDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->FractionDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void NumeralSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->NumeralSystem;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumeralSystemSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->NumeralSystem = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void GeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->GeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LanguagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->Languages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Platform::String^>::CreateVectorViewWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedGeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedGeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedLanguageGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedLanguage;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::INumberRounder^ result = wrapper->_instance->NumberRounder;
        info.GetReturnValue().Set(WrapINumberRounder(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::INumberRounder^ winRtValue = dynamic_cast<::Windows::Globalization::NumberFormatting::INumberRounder^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->NumberRounder = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsZeroSignedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsZeroSigned;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsZeroSignedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsZeroSigned = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void SignificantDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->SignificantDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SignificantDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::DecimalFormatter^>(info.This()))
      {
        return;
      }

      DecimalFormatter *wrapper = DecimalFormatter::Unwrap<DecimalFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SignificantDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::DecimalFormatter^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapDecimalFormatter(::Windows::Globalization::NumberFormatting::DecimalFormatter^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::DecimalFormatter^ UnwrapDecimalFormatter(Local<Value> value);
  };
  Persistent<FunctionTemplate> DecimalFormatter::s_constructorTemplate;

  v8::Local<v8::Value> WrapDecimalFormatter(::Windows::Globalization::NumberFormatting::DecimalFormatter^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(DecimalFormatter::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::DecimalFormatter^ UnwrapDecimalFormatter(Local<Value> value)
  {
     return DecimalFormatter::Unwrap<DecimalFormatter>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitDecimalFormatter(Local<Object> exports)
  {
    DecimalFormatter::Init(exports);
  }

  class PercentFormatter : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("PercentFormatter").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "format", Format);
      Nan::SetPrototypeMethod(localRef, "formatInt", FormatInt);
      Nan::SetPrototypeMethod(localRef, "formatUInt", FormatUInt);
      Nan::SetPrototypeMethod(localRef, "formatDouble", FormatDouble);
      Nan::SetPrototypeMethod(localRef, "parseInt", ParseInt);
      Nan::SetPrototypeMethod(localRef, "parseUInt", ParseUInt);
      Nan::SetPrototypeMethod(localRef, "parseDouble", ParseDouble);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isDecimalPointAlwaysDisplayed").ToLocalChecked(), IsDecimalPointAlwaysDisplayedGetter, IsDecimalPointAlwaysDisplayedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("integerDigits").ToLocalChecked(), IntegerDigitsGetter, IntegerDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isGrouped").ToLocalChecked(), IsGroupedGetter, IsGroupedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("fractionDigits").ToLocalChecked(), FractionDigitsGetter, FractionDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numeralSystem").ToLocalChecked(), NumeralSystemGetter, NumeralSystemSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("geographicRegion").ToLocalChecked(), GeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("languages").ToLocalChecked(), LanguagesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedGeographicRegion").ToLocalChecked(), ResolvedGeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedLanguage").ToLocalChecked(), ResolvedLanguageGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numberRounder").ToLocalChecked(), NumberRounderGetter, NumberRounderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isZeroSigned").ToLocalChecked(), IsZeroSignedGetter, IsZeroSignedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("significantDigits").ToLocalChecked(), SignificantDigitsGetter, SignificantDigitsSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PercentFormatter").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PercentFormatter(::Windows::Globalization::NumberFormatting::PercentFormatter^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::PercentFormatter^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::PercentFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(info[0]) || info[0]->IsArray())
        && info[1]->IsString())
      {
        try
        {
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Local<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::PercentFormatter(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::PercentFormatter();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      PercentFormatter *wrapperInstance = new PercentFormatter(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::PercentFormatter^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::PercentFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPercentFormatter(winRtInstance));
    }


  
    static void Format(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->FormatUInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatDouble(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<__int64>^ result;
          result = wrapper->_instance->ParseInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<unsigned __int64>^ result;
          result = wrapper->_instance->ParseUInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<double>^ result;
          result = wrapper->_instance->ParseDouble(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    static void IsDecimalPointAlwaysDisplayedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsDecimalPointAlwaysDisplayed;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsDecimalPointAlwaysDisplayedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsDecimalPointAlwaysDisplayed = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IntegerDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->IntegerDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IntegerDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->IntegerDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsGroupedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsGrouped;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsGroupedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsGrouped = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void FractionDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->FractionDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FractionDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->FractionDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void NumeralSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->NumeralSystem;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumeralSystemSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->NumeralSystem = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void GeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->GeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LanguagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->Languages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Platform::String^>::CreateVectorViewWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedGeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedGeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedLanguageGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedLanguage;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::INumberRounder^ result = wrapper->_instance->NumberRounder;
        info.GetReturnValue().Set(WrapINumberRounder(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::INumberRounder^ winRtValue = dynamic_cast<::Windows::Globalization::NumberFormatting::INumberRounder^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->NumberRounder = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsZeroSignedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsZeroSigned;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsZeroSignedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsZeroSigned = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void SignificantDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->SignificantDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SignificantDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PercentFormatter^>(info.This()))
      {
        return;
      }

      PercentFormatter *wrapper = PercentFormatter::Unwrap<PercentFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SignificantDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::PercentFormatter^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPercentFormatter(::Windows::Globalization::NumberFormatting::PercentFormatter^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::PercentFormatter^ UnwrapPercentFormatter(Local<Value> value);
  };
  Persistent<FunctionTemplate> PercentFormatter::s_constructorTemplate;

  v8::Local<v8::Value> WrapPercentFormatter(::Windows::Globalization::NumberFormatting::PercentFormatter^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(PercentFormatter::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::PercentFormatter^ UnwrapPercentFormatter(Local<Value> value)
  {
     return PercentFormatter::Unwrap<PercentFormatter>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPercentFormatter(Local<Object> exports)
  {
    PercentFormatter::Init(exports);
  }

  class PermilleFormatter : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("PermilleFormatter").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "format", Format);
      Nan::SetPrototypeMethod(localRef, "formatInt", FormatInt);
      Nan::SetPrototypeMethod(localRef, "formatUInt", FormatUInt);
      Nan::SetPrototypeMethod(localRef, "formatDouble", FormatDouble);
      Nan::SetPrototypeMethod(localRef, "parseInt", ParseInt);
      Nan::SetPrototypeMethod(localRef, "parseUInt", ParseUInt);
      Nan::SetPrototypeMethod(localRef, "parseDouble", ParseDouble);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isDecimalPointAlwaysDisplayed").ToLocalChecked(), IsDecimalPointAlwaysDisplayedGetter, IsDecimalPointAlwaysDisplayedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("integerDigits").ToLocalChecked(), IntegerDigitsGetter, IntegerDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isGrouped").ToLocalChecked(), IsGroupedGetter, IsGroupedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("fractionDigits").ToLocalChecked(), FractionDigitsGetter, FractionDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numeralSystem").ToLocalChecked(), NumeralSystemGetter, NumeralSystemSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("geographicRegion").ToLocalChecked(), GeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("languages").ToLocalChecked(), LanguagesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedGeographicRegion").ToLocalChecked(), ResolvedGeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedLanguage").ToLocalChecked(), ResolvedLanguageGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numberRounder").ToLocalChecked(), NumberRounderGetter, NumberRounderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isZeroSigned").ToLocalChecked(), IsZeroSignedGetter, IsZeroSignedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("significantDigits").ToLocalChecked(), SignificantDigitsGetter, SignificantDigitsSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PermilleFormatter").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PermilleFormatter(::Windows::Globalization::NumberFormatting::PermilleFormatter^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::PermilleFormatter^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::PermilleFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(info[0]) || info[0]->IsArray())
        && info[1]->IsString())
      {
        try
        {
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Local<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::PermilleFormatter(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::PermilleFormatter();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      PermilleFormatter *wrapperInstance = new PermilleFormatter(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::PermilleFormatter^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::PermilleFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPermilleFormatter(winRtInstance));
    }


  
    static void Format(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->FormatUInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatDouble(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<__int64>^ result;
          result = wrapper->_instance->ParseInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<unsigned __int64>^ result;
          result = wrapper->_instance->ParseUInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<double>^ result;
          result = wrapper->_instance->ParseDouble(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    static void IsDecimalPointAlwaysDisplayedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsDecimalPointAlwaysDisplayed;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsDecimalPointAlwaysDisplayedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsDecimalPointAlwaysDisplayed = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IntegerDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->IntegerDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IntegerDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->IntegerDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsGroupedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsGrouped;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsGroupedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsGrouped = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void FractionDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->FractionDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FractionDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->FractionDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void NumeralSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->NumeralSystem;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumeralSystemSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->NumeralSystem = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void GeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->GeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LanguagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->Languages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Platform::String^>::CreateVectorViewWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedGeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedGeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedLanguageGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedLanguage;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::INumberRounder^ result = wrapper->_instance->NumberRounder;
        info.GetReturnValue().Set(WrapINumberRounder(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::INumberRounder^ winRtValue = dynamic_cast<::Windows::Globalization::NumberFormatting::INumberRounder^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->NumberRounder = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsZeroSignedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsZeroSigned;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsZeroSignedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsZeroSigned = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void SignificantDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->SignificantDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SignificantDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::PermilleFormatter^>(info.This()))
      {
        return;
      }

      PermilleFormatter *wrapper = PermilleFormatter::Unwrap<PermilleFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SignificantDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::PermilleFormatter^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPermilleFormatter(::Windows::Globalization::NumberFormatting::PermilleFormatter^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::PermilleFormatter^ UnwrapPermilleFormatter(Local<Value> value);
  };
  Persistent<FunctionTemplate> PermilleFormatter::s_constructorTemplate;

  v8::Local<v8::Value> WrapPermilleFormatter(::Windows::Globalization::NumberFormatting::PermilleFormatter^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(PermilleFormatter::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::PermilleFormatter^ UnwrapPermilleFormatter(Local<Value> value)
  {
     return PermilleFormatter::Unwrap<PermilleFormatter>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPermilleFormatter(Local<Object> exports)
  {
    PermilleFormatter::Init(exports);
  }

  class CurrencyFormatter : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("CurrencyFormatter").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "format", Format);
      Nan::SetPrototypeMethod(localRef, "formatInt", FormatInt);
      Nan::SetPrototypeMethod(localRef, "formatUInt", FormatUInt);
      Nan::SetPrototypeMethod(localRef, "formatDouble", FormatDouble);
      Nan::SetPrototypeMethod(localRef, "parseInt", ParseInt);
      Nan::SetPrototypeMethod(localRef, "parseUInt", ParseUInt);
      Nan::SetPrototypeMethod(localRef, "parseDouble", ParseDouble);
      Nan::SetPrototypeMethod(localRef, "applyRoundingForCurrency", ApplyRoundingForCurrency);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("currency").ToLocalChecked(), CurrencyGetter, CurrencySetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("mode").ToLocalChecked(), ModeGetter, ModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isGrouped").ToLocalChecked(), IsGroupedGetter, IsGroupedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isDecimalPointAlwaysDisplayed").ToLocalChecked(), IsDecimalPointAlwaysDisplayedGetter, IsDecimalPointAlwaysDisplayedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("integerDigits").ToLocalChecked(), IntegerDigitsGetter, IntegerDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("fractionDigits").ToLocalChecked(), FractionDigitsGetter, FractionDigitsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numeralSystem").ToLocalChecked(), NumeralSystemGetter, NumeralSystemSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("geographicRegion").ToLocalChecked(), GeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedGeographicRegion").ToLocalChecked(), ResolvedGeographicRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedLanguage").ToLocalChecked(), ResolvedLanguageGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("languages").ToLocalChecked(), LanguagesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numberRounder").ToLocalChecked(), NumberRounderGetter, NumberRounderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isZeroSigned").ToLocalChecked(), IsZeroSignedGetter, IsZeroSignedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("significantDigits").ToLocalChecked(), SignificantDigitsGetter, SignificantDigitsSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("CurrencyFormatter").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CurrencyFormatter(::Windows::Globalization::NumberFormatting::CurrencyFormatter^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::CurrencyFormatter^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::CurrencyFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::CurrencyFormatter(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 3
        && info[0]->IsString()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(info[1]) || info[1]->IsArray())
        && info[2]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Local<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          Platform::String^ arg2 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[2])));
          
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::CurrencyFormatter(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      CurrencyFormatter *wrapperInstance = new CurrencyFormatter(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::CurrencyFormatter^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::CurrencyFormatter^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCurrencyFormatter(winRtInstance));
    }


  
    static void Format(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->Format(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          __int64 arg0 = Nan::To<int64_t>(info[0]).FromMaybe(0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          Platform::String^ result;
          result = wrapper->_instance->FormatUInt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void FormatDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          double arg0 = Nan::To<double>(info[0]).FromMaybe(0.0);
          
          Platform::String^ result;
          result = wrapper->_instance->FormatDouble(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<__int64>^ result;
          result = wrapper->_instance->ParseInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseUInt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<unsigned __int64>^ result;
          result = wrapper->_instance->ParseUInt(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ParseDouble(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Platform::IBox<double>^ result;
          result = wrapper->_instance->ParseDouble(arg0);
          info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void ApplyRoundingForCurrency(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Globalization::NumberFormatting::RoundingAlgorithm arg0 = static_cast<::Windows::Globalization::NumberFormatting::RoundingAlgorithm>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          wrapper->_instance->ApplyRoundingForCurrency(arg0);
          return;   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    static void CurrencyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->Currency;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CurrencySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->Currency = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::CurrencyFormatterMode result = wrapper->_instance->Mode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ModeSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::CurrencyFormatterMode winRtValue = static_cast<::Windows::Globalization::NumberFormatting::CurrencyFormatterMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Mode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsGroupedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsGrouped;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsGroupedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsGrouped = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsDecimalPointAlwaysDisplayedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsDecimalPointAlwaysDisplayed;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsDecimalPointAlwaysDisplayedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsDecimalPointAlwaysDisplayed = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IntegerDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->IntegerDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IntegerDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->IntegerDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void FractionDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->FractionDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FractionDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->FractionDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void NumeralSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->NumeralSystem;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumeralSystemSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->NumeralSystem = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void GeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->GeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedGeographicRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedGeographicRegion;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedLanguageGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedLanguage;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LanguagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->Languages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Platform::String^>::CreateVectorViewWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        ::Windows::Globalization::NumberFormatting::INumberRounder^ result = wrapper->_instance->NumberRounder;
        info.GetReturnValue().Set(WrapINumberRounder(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumberRounderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::INumberRounder^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        ::Windows::Globalization::NumberFormatting::INumberRounder^ winRtValue = dynamic_cast<::Windows::Globalization::NumberFormatting::INumberRounder^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->NumberRounder = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsZeroSignedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsZeroSigned;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsZeroSignedSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsBoolean())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsZeroSigned = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void SignificantDigitsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        int result = wrapper->_instance->SignificantDigits;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SignificantDigitsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::CurrencyFormatter^>(info.This()))
      {
        return;
      }

      CurrencyFormatter *wrapper = CurrencyFormatter::Unwrap<CurrencyFormatter>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SignificantDigits = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::CurrencyFormatter^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCurrencyFormatter(::Windows::Globalization::NumberFormatting::CurrencyFormatter^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::CurrencyFormatter^ UnwrapCurrencyFormatter(Local<Value> value);
  };
  Persistent<FunctionTemplate> CurrencyFormatter::s_constructorTemplate;

  v8::Local<v8::Value> WrapCurrencyFormatter(::Windows::Globalization::NumberFormatting::CurrencyFormatter^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(CurrencyFormatter::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::CurrencyFormatter^ UnwrapCurrencyFormatter(Local<Value> value)
  {
     return CurrencyFormatter::Unwrap<CurrencyFormatter>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCurrencyFormatter(Local<Object> exports)
  {
    CurrencyFormatter::Init(exports);
  }

  class NumeralSystemTranslator : public WrapperBase
  {
  public:    
    static void Init(const Local<Object> exports)
    {
      HandleScope scope;
      
      Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(New);
      s_constructorTemplate.Reset(localRef);
      localRef->SetClassName(Nan::New<String>("NumeralSystemTranslator").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "translateNumerals", TranslateNumerals);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("numeralSystem").ToLocalChecked(), NumeralSystemGetter, NumeralSystemSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("languages").ToLocalChecked(), LanguagesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("resolvedLanguage").ToLocalChecked(), ResolvedLanguageGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NumeralSystemTranslator").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NumeralSystemTranslator(::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ instance)
    {
      _instance = instance;
    }
    
    
    static void New(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

	    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(s_constructorTemplate);

      // in case the constructor was called without the new operator
      if (!localRef->HasInstance(info.This()))
      {
        if (info.Length() > 0)
        {
          std::unique_ptr<Local<Value> []> constructorArgs(new Local<Value>[info.Length()]);

          Local<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < info.Length(); i++)
          {
            argsPtr[i] = info[i];
          }

		  MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), constructorArgs.get());
		  if (res.IsEmpty())
		  {
			  return;
		  }
		  info.GetReturnValue().Set(res.ToLocalChecked());
		  return;
		}
		else
		{
          MaybeLocal<Object> res = Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(), info.Length(), nullptr);
          if (res.IsEmpty())
          {
            return;
          }
          info.GetReturnValue().Set(res.ToLocalChecked());
          return;
        }
      }
      
      ::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Local<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::NumeralSystemTranslator(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Globalization::NumberFormatting::NumeralSystemTranslator();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      NumeralSystemTranslator *wrapperInstance = new NumeralSystemTranslator(winRtInstance);
      wrapperInstance->Wrap(info.This());

      info.GetReturnValue().Set(info.This());
    }


	
    static void CastFrom(Nan::NAN_METHOD_ARGS_TYPE info)
    {
		HandleScope scope;
		if (info.Length() < 1 || !NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^>(info[0]))
		{
			Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no object provided, or given object could not be casted to requested type")));
			return;
		}

		::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNumeralSystemTranslator(winRtInstance));
    }


  
    static void TranslateNumerals(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^>(info.This()))
      {
        return;
      }

      NumeralSystemTranslator *wrapper = NumeralSystemTranslator::Unwrap<NumeralSystemTranslator>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          Platform::String^ result;
          result = wrapper->_instance->TranslateNumerals(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    static void NumeralSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^>(info.This()))
      {
        return;
      }

      NumeralSystemTranslator *wrapper = NumeralSystemTranslator::Unwrap<NumeralSystemTranslator>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->NumeralSystem;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NumeralSystemSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^>(info.This()))
      {
        return;
      }

      NumeralSystemTranslator *wrapper = NumeralSystemTranslator::Unwrap<NumeralSystemTranslator>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->NumeralSystem = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void LanguagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^>(info.This()))
      {
        return;
      }

      NumeralSystemTranslator *wrapper = NumeralSystemTranslator::Unwrap<NumeralSystemTranslator>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->Languages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Platform::String^>::CreateVectorViewWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ResolvedLanguageGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^>(info.This()))
      {
        return;
      }

      NumeralSystemTranslator *wrapper = NumeralSystemTranslator::Unwrap<NumeralSystemTranslator>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResolvedLanguage;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNumeralSystemTranslator(::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ wintRtInstance);
    friend ::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ UnwrapNumeralSystemTranslator(Local<Value> value);
  };
  Persistent<FunctionTemplate> NumeralSystemTranslator::s_constructorTemplate;

  v8::Local<v8::Value> WrapNumeralSystemTranslator(::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ winRtInstance)
  {
    EscapableHandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Escape(Undefined());
    }

    Local<Value> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Local<Value> args[] = {opaqueWrapper};
    Local<FunctionTemplate> localRef = Nan::New<FunctionTemplate>(NumeralSystemTranslator::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Globalization::NumberFormatting::NumeralSystemTranslator^ UnwrapNumeralSystemTranslator(Local<Value> value)
  {
     return NumeralSystemTranslator::Unwrap<NumeralSystemTranslator>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNumeralSystemTranslator(Local<Object> exports)
  {
    NumeralSystemTranslator::Init(exports);
  }

} } } } 

NAN_MODULE_INIT(init)
{
  // we ignore failures for now since it probably means that the initialization already happened for STA, and that's cool
  CoInitializeEx(nullptr, COINIT_MULTITHREADED);
  //if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
  /*{
    Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"error in CoInitializeEx()")));
    return;
  }*/
  
  NodeRT::Windows::Globalization::NumberFormatting::InitRoundingAlgorithmEnum(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitCurrencyFormatterModeEnum(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitINumberRounder(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitSignificantDigitsNumberRounder(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitIncrementNumberRounder(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitINumberFormatter(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitINumberFormatter2(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitINumberParser(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitINumberFormatterOptions(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitISignificantDigitsOption(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitINumberRounderOption(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitISignedZeroOption(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitDecimalFormatter(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitPercentFormatter(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitPermilleFormatter(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitCurrencyFormatter(target);
  NodeRT::Windows::Globalization::NumberFormatting::InitNumeralSystemTranslator(target);

  NodeRT::Utils::RegisterNameSpace("Windows.Globalization.NumberFormatting", target);
}


NODE_MODULE(binding, init)