// Copyright (c) The NodeRT Contributors
// 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::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 Security { namespace Cryptography { namespace Core { 
  v8::Local<v8::Value> WrapKeyDerivationParameters(::Windows::Security::Cryptography::Core::KeyDerivationParameters^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ UnwrapKeyDerivationParameters(Local<Value> value);
  
  v8::Local<v8::Value> WrapCryptographicKey(::Windows::Security::Cryptography::Core::CryptographicKey^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::CryptographicKey^ UnwrapCryptographicKey(Local<Value> value);
  
  v8::Local<v8::Value> WrapCryptographicHash(::Windows::Security::Cryptography::Core::CryptographicHash^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::CryptographicHash^ UnwrapCryptographicHash(Local<Value> value);
  
  v8::Local<v8::Value> WrapPersistedKeyProvider(::Windows::Security::Cryptography::Core::PersistedKeyProvider^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::PersistedKeyProvider^ UnwrapPersistedKeyProvider(Local<Value> value);
  
  v8::Local<v8::Value> WrapEncryptedAndAuthenticatedData(::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ UnwrapEncryptedAndAuthenticatedData(Local<Value> value);
  
  v8::Local<v8::Value> WrapCryptographicEngine(::Windows::Security::Cryptography::Core::CryptographicEngine^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::CryptographicEngine^ UnwrapCryptographicEngine(Local<Value> value);
  
  v8::Local<v8::Value> WrapHashAlgorithmProvider(::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ UnwrapHashAlgorithmProvider(Local<Value> value);
  
  v8::Local<v8::Value> WrapMacAlgorithmProvider(::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ UnwrapMacAlgorithmProvider(Local<Value> value);
  
  v8::Local<v8::Value> WrapKeyDerivationAlgorithmProvider(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ UnwrapKeyDerivationAlgorithmProvider(Local<Value> value);
  
  v8::Local<v8::Value> WrapSymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ UnwrapSymmetricKeyAlgorithmProvider(Local<Value> value);
  
  v8::Local<v8::Value> WrapAsymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ UnwrapAsymmetricKeyAlgorithmProvider(Local<Value> value);
  
  v8::Local<v8::Value> WrapHashAlgorithmNames(::Windows::Security::Cryptography::Core::HashAlgorithmNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::HashAlgorithmNames^ UnwrapHashAlgorithmNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapMacAlgorithmNames(::Windows::Security::Cryptography::Core::MacAlgorithmNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::MacAlgorithmNames^ UnwrapMacAlgorithmNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapSymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ UnwrapSymmetricAlgorithmNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapAsymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ UnwrapAsymmetricAlgorithmNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapEccCurveNames(::Windows::Security::Cryptography::Core::EccCurveNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::EccCurveNames^ UnwrapEccCurveNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapKeyDerivationAlgorithmNames(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ UnwrapKeyDerivationAlgorithmNames(Local<Value> value);
  



  static void InitCryptographicPrivateKeyBlobTypeEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("CryptographicPrivateKeyBlobType").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("pkcs8RawPrivateKeyInfo").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType::Pkcs8RawPrivateKeyInfo)));
    Nan::Set(enumObject, Nan::New<String>("pkcs1RsaPrivateKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType::Pkcs1RsaPrivateKey)));
    Nan::Set(enumObject, Nan::New<String>("bCryptPrivateKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType::BCryptPrivateKey)));
    Nan::Set(enumObject, Nan::New<String>("capi1PrivateKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType::Capi1PrivateKey)));
    Nan::Set(enumObject, Nan::New<String>("bCryptEccFullPrivateKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType::BCryptEccFullPrivateKey)));
  }

  static void InitCryptographicPublicKeyBlobTypeEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("CryptographicPublicKeyBlobType").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("x509SubjectPublicKeyInfo").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType::X509SubjectPublicKeyInfo)));
    Nan::Set(enumObject, Nan::New<String>("pkcs1RsaPublicKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType::Pkcs1RsaPublicKey)));
    Nan::Set(enumObject, Nan::New<String>("bCryptPublicKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType::BCryptPublicKey)));
    Nan::Set(enumObject, Nan::New<String>("capi1PublicKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType::Capi1PublicKey)));
    Nan::Set(enumObject, Nan::New<String>("bCryptEccFullPublicKey").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType::BCryptEccFullPublicKey)));
  }

  static void InitCapi1KdfTargetAlgorithmEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("Capi1KdfTargetAlgorithm").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("notAes").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::Capi1KdfTargetAlgorithm::NotAes)));
    Nan::Set(enumObject, Nan::New<String>("aes").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::Capi1KdfTargetAlgorithm::Aes)));
  }

  static void InitCryptographicPaddingEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("CryptographicPadding").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("none").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPadding::None)));
    Nan::Set(enumObject, Nan::New<String>("rsaOaep").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPadding::RsaOaep)));
    Nan::Set(enumObject, Nan::New<String>("rsaPkcs1V15").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPadding::RsaPkcs1V15)));
    Nan::Set(enumObject, Nan::New<String>("rsaPss").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Core::CryptographicPadding::RsaPss)));
  }



  class KeyDerivationParameters : 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>("KeyDerivationParameters").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("kdfGenericBinary").ToLocalChecked(), KdfGenericBinaryGetter, KdfGenericBinarySetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("iterationCount").ToLocalChecked(), IterationCountGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("capi1KdfTargetAlgorithm").ToLocalChecked(), Capi1KdfTargetAlgorithmGetter, Capi1KdfTargetAlgorithmSetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "buildForCapi1Kdf", BuildForCapi1Kdf);
        Nan::SetMethod(constructor, "buildForPbkdf2", BuildForPbkdf2);
        Nan::SetMethod(constructor, "buildForSP800108", BuildForSP800108);
        Nan::SetMethod(constructor, "buildForSP80056a", BuildForSP80056a);


        Nan::Set(exports, Nan::New<String>("KeyDerivationParameters").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      KeyDerivationParameters(::Windows::Security::Cryptography::Core::KeyDerivationParameters^ 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::Security::Cryptography::Core::KeyDerivationParameters^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationParameters^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::KeyDerivationParameters^) 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());

      KeyDerivationParameters *wrapperInstance = new KeyDerivationParameters(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::Security::Cryptography::Core::KeyDerivationParameters^>(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::Security::Cryptography::Core::KeyDerivationParameters^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::KeyDerivationParameters^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapKeyDerivationParameters(winRtInstance));
    }





    static void BuildForCapi1Kdf(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Security::Cryptography::Core::Capi1KdfTargetAlgorithm arg0 = static_cast<::Windows::Security::Cryptography::Core::Capi1KdfTargetAlgorithm>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ result;
          result = ::Windows::Security::Cryptography::Core::KeyDerivationParameters::BuildForCapi1Kdf(arg0);
          info.GetReturnValue().Set(WrapKeyDerivationParameters(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 BuildForPbkdf2(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0])
        && info[1]->IsUint32())
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          unsigned int arg1 = static_cast<unsigned int>(Nan::To<uint32_t>(info[1]).FromMaybe(0));
          
          ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ result;
          result = ::Windows::Security::Cryptography::Core::KeyDerivationParameters::BuildForPbkdf2(arg0, arg1);
          info.GetReturnValue().Set(WrapKeyDerivationParameters(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 BuildForSP800108(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ result;
          result = ::Windows::Security::Cryptography::Core::KeyDerivationParameters::BuildForSP800108(arg0, arg1);
          info.GetReturnValue().Set(WrapKeyDerivationParameters(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 BuildForSP80056a(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 5
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[3])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[4]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
          ::Windows::Storage::Streams::IBuffer^ arg3 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[3]));
          ::Windows::Storage::Streams::IBuffer^ arg4 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[4]));
          
          ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ result;
          result = ::Windows::Security::Cryptography::Core::KeyDerivationParameters::BuildForSP80056a(arg0, arg1, arg2, arg3, arg4);
          info.GetReturnValue().Set(WrapKeyDerivationParameters(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 KdfGenericBinaryGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationParameters^>(info.This())) {
        return;
      }

      KeyDerivationParameters *wrapper = KeyDerivationParameters::Unwrap<KeyDerivationParameters>(info.This());

      try  {
        ::Windows::Storage::Streams::IBuffer^ result = wrapper->_instance->KdfGenericBinary;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KdfGenericBinarySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(value)) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationParameters^>(info.This())) {
        return;
      }

      KeyDerivationParameters *wrapper = KeyDerivationParameters::Unwrap<KeyDerivationParameters>(info.This());

      try {

        ::Windows::Storage::Streams::IBuffer^ winRtValue = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->KdfGenericBinary = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void IterationCountGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationParameters^>(info.This())) {
        return;
      }

      KeyDerivationParameters *wrapper = KeyDerivationParameters::Unwrap<KeyDerivationParameters>(info.This());

      try  {
        unsigned int result = wrapper->_instance->IterationCount;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void Capi1KdfTargetAlgorithmGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationParameters^>(info.This())) {
        return;
      }

      KeyDerivationParameters *wrapper = KeyDerivationParameters::Unwrap<KeyDerivationParameters>(info.This());

      try  {
        ::Windows::Security::Cryptography::Core::Capi1KdfTargetAlgorithm result = wrapper->_instance->Capi1KdfTargetAlgorithm;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void Capi1KdfTargetAlgorithmSetter(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::Security::Cryptography::Core::KeyDerivationParameters^>(info.This())) {
        return;
      }

      KeyDerivationParameters *wrapper = KeyDerivationParameters::Unwrap<KeyDerivationParameters>(info.This());

      try {

        ::Windows::Security::Cryptography::Core::Capi1KdfTargetAlgorithm winRtValue = static_cast<::Windows::Security::Cryptography::Core::Capi1KdfTargetAlgorithm>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Capi1KdfTargetAlgorithm = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapKeyDerivationParameters(::Windows::Security::Cryptography::Core::KeyDerivationParameters^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ UnwrapKeyDerivationParameters(Local<Value> value);
  };

  Persistent<FunctionTemplate> KeyDerivationParameters::s_constructorTemplate;

  v8::Local<v8::Value> WrapKeyDerivationParameters(::Windows::Security::Cryptography::Core::KeyDerivationParameters^ 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>(KeyDerivationParameters::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ UnwrapKeyDerivationParameters(Local<Value> value) {
     return KeyDerivationParameters::Unwrap<KeyDerivationParameters>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitKeyDerivationParameters(Local<Object> exports) {
    KeyDerivationParameters::Init(exports);
  }

  class CryptographicKey : 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>("CryptographicKey").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "export", Export);
            Nan::SetPrototypeMethod(localRef, "exportPublicKey", ExportPublicKey);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keySize").ToLocalChecked(), KeySizeGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CryptographicKey").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CryptographicKey(::Windows::Security::Cryptography::Core::CryptographicKey^ 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::Security::Cryptography::Core::CryptographicKey^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::CryptographicKey^) 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());

      CryptographicKey *wrapperInstance = new CryptographicKey(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::Security::Cryptography::Core::CryptographicKey^>(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::Security::Cryptography::Core::CryptographicKey^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::CryptographicKey^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCryptographicKey(winRtInstance));
    }


    static void Export(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info.This())) {
        return;
      }

      CryptographicKey *wrapper = CryptographicKey::Unwrap<CryptographicKey>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ result;
          result = wrapper->_instance->Export();
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result));
          return;
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType arg0 = static_cast<::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = wrapper->_instance->Export(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 ExportPublicKey(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info.This())) {
        return;
      }

      CryptographicKey *wrapper = CryptographicKey::Unwrap<CryptographicKey>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ result;
          result = wrapper->_instance->ExportPublicKey();
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result));
          return;
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType arg0 = static_cast<::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = wrapper->_instance->ExportPublicKey(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 KeySizeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info.This())) {
        return;
      }

      CryptographicKey *wrapper = CryptographicKey::Unwrap<CryptographicKey>(info.This());

      try  {
        unsigned int result = wrapper->_instance->KeySize;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::CryptographicKey^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCryptographicKey(::Windows::Security::Cryptography::Core::CryptographicKey^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::CryptographicKey^ UnwrapCryptographicKey(Local<Value> value);
  };

  Persistent<FunctionTemplate> CryptographicKey::s_constructorTemplate;

  v8::Local<v8::Value> WrapCryptographicKey(::Windows::Security::Cryptography::Core::CryptographicKey^ 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>(CryptographicKey::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::CryptographicKey^ UnwrapCryptographicKey(Local<Value> value) {
     return CryptographicKey::Unwrap<CryptographicKey>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCryptographicKey(Local<Object> exports) {
    CryptographicKey::Init(exports);
  }

  class CryptographicHash : 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>("CryptographicHash").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "append", Append);
            Nan::SetPrototypeMethod(localRef, "getValueAndReset", GetValueAndReset);
          




        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CryptographicHash").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CryptographicHash(::Windows::Security::Cryptography::Core::CryptographicHash^ 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::Security::Cryptography::Core::CryptographicHash^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicHash^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::CryptographicHash^) 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());

      CryptographicHash *wrapperInstance = new CryptographicHash(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::Security::Cryptography::Core::CryptographicHash^>(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::Security::Cryptography::Core::CryptographicHash^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::CryptographicHash^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCryptographicHash(winRtInstance));
    }


    static void Append(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicHash^>(info.This())) {
        return;
      }

      CryptographicHash *wrapper = CryptographicHash::Unwrap<CryptographicHash>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          wrapper->_instance->Append(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 GetValueAndReset(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicHash^>(info.This())) {
        return;
      }

      CryptographicHash *wrapper = CryptographicHash::Unwrap<CryptographicHash>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ result;
          result = wrapper->_instance->GetValueAndReset();
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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::Security::Cryptography::Core::CryptographicHash^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCryptographicHash(::Windows::Security::Cryptography::Core::CryptographicHash^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::CryptographicHash^ UnwrapCryptographicHash(Local<Value> value);
  };

  Persistent<FunctionTemplate> CryptographicHash::s_constructorTemplate;

  v8::Local<v8::Value> WrapCryptographicHash(::Windows::Security::Cryptography::Core::CryptographicHash^ 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>(CryptographicHash::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::CryptographicHash^ UnwrapCryptographicHash(Local<Value> value) {
     return CryptographicHash::Unwrap<CryptographicHash>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCryptographicHash(Local<Object> exports) {
    CryptographicHash::Init(exports);
  }

  class PersistedKeyProvider : 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>("PersistedKeyProvider").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);

        Local<Function> func;
        Local<FunctionTemplate> funcTemplate;





        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "openPublicKeyFromCertificate", OpenPublicKeyFromCertificate);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(OpenKeyPairFromCertificateAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("openKeyPairFromCertificateAsync").ToLocalChecked(), func);


        Nan::Set(exports, Nan::New<String>("PersistedKeyProvider").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      PersistedKeyProvider(::Windows::Security::Cryptography::Core::PersistedKeyProvider^ 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::Security::Cryptography::Core::PersistedKeyProvider^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::PersistedKeyProvider^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::PersistedKeyProvider^) 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());

      PersistedKeyProvider *wrapperInstance = new PersistedKeyProvider(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::Security::Cryptography::Core::PersistedKeyProvider^>(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::Security::Cryptography::Core::PersistedKeyProvider^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::PersistedKeyProvider^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapPersistedKeyProvider(winRtInstance));
    }




    static void OpenKeyPairFromCertificateAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      ::Windows::Foundation::IAsyncOperation<::Windows::Security::Cryptography::Core::CryptographicKey^>^ op;


      if (info.Length() == 4
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info[0])
          && info[1]->IsString()
          && info[2]->IsInt32())
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::Certificate^ arg0 = dynamic_cast<::Windows::Security::Cryptography::Certificates::Certificate^>(NodeRT::Utils::GetObjectInstance(info[0]));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Core::CryptographicPadding arg2 = static_cast<::Windows::Security::Cryptography::Core::CryptographicPadding>(Nan::To<int32_t>(info[2]).FromMaybe(0));
            
          op = ::Windows::Security::Cryptography::Core::PersistedKeyProvider::OpenKeyPairFromCertificateAsync(arg0,arg1,arg2);
        } 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;
      }

      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Security::Cryptography::Core::CryptographicKey^> t)
      {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = WrapCryptographicKey(result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {

            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }


    static void OpenPublicKeyFromCertificate(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info[0])
        && info[1]->IsString()
        && info[2]->IsInt32())
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::Certificate^ arg0 = dynamic_cast<::Windows::Security::Cryptography::Certificates::Certificate^>(NodeRT::Utils::GetObjectInstance(info[0]));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Core::CryptographicPadding arg2 = static_cast<::Windows::Security::Cryptography::Core::CryptographicPadding>(Nan::To<int32_t>(info[2]).FromMaybe(0));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = ::Windows::Security::Cryptography::Core::PersistedKeyProvider::OpenPublicKeyFromCertificate(arg0, arg1, arg2);
          info.GetReturnValue().Set(WrapCryptographicKey(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::Security::Cryptography::Core::PersistedKeyProvider^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapPersistedKeyProvider(::Windows::Security::Cryptography::Core::PersistedKeyProvider^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::PersistedKeyProvider^ UnwrapPersistedKeyProvider(Local<Value> value);
  };

  Persistent<FunctionTemplate> PersistedKeyProvider::s_constructorTemplate;

  v8::Local<v8::Value> WrapPersistedKeyProvider(::Windows::Security::Cryptography::Core::PersistedKeyProvider^ 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>(PersistedKeyProvider::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::PersistedKeyProvider^ UnwrapPersistedKeyProvider(Local<Value> value) {
     return PersistedKeyProvider::Unwrap<PersistedKeyProvider>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPersistedKeyProvider(Local<Object> exports) {
    PersistedKeyProvider::Init(exports);
  }

  class EncryptedAndAuthenticatedData : 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>("EncryptedAndAuthenticatedData").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("authenticationTag").ToLocalChecked(), AuthenticationTagGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("encryptedData").ToLocalChecked(), EncryptedDataGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("EncryptedAndAuthenticatedData").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      EncryptedAndAuthenticatedData(::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ 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::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^) 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());

      EncryptedAndAuthenticatedData *wrapperInstance = new EncryptedAndAuthenticatedData(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::Security::Cryptography::Core::EncryptedAndAuthenticatedData^>(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::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapEncryptedAndAuthenticatedData(winRtInstance));
    }





    static void AuthenticationTagGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^>(info.This())) {
        return;
      }

      EncryptedAndAuthenticatedData *wrapper = EncryptedAndAuthenticatedData::Unwrap<EncryptedAndAuthenticatedData>(info.This());

      try  {
        ::Windows::Storage::Streams::IBuffer^ result = wrapper->_instance->AuthenticationTag;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void EncryptedDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^>(info.This())) {
        return;
      }

      EncryptedAndAuthenticatedData *wrapper = EncryptedAndAuthenticatedData::Unwrap<EncryptedAndAuthenticatedData>(info.This());

      try  {
        ::Windows::Storage::Streams::IBuffer^ result = wrapper->_instance->EncryptedData;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapEncryptedAndAuthenticatedData(::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ UnwrapEncryptedAndAuthenticatedData(Local<Value> value);
  };

  Persistent<FunctionTemplate> EncryptedAndAuthenticatedData::s_constructorTemplate;

  v8::Local<v8::Value> WrapEncryptedAndAuthenticatedData(::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ 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>(EncryptedAndAuthenticatedData::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ UnwrapEncryptedAndAuthenticatedData(Local<Value> value) {
     return EncryptedAndAuthenticatedData::Unwrap<EncryptedAndAuthenticatedData>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitEncryptedAndAuthenticatedData(Local<Object> exports) {
    EncryptedAndAuthenticatedData::Init(exports);
  }

  class CryptographicEngine : 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>("CryptographicEngine").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);

        Local<Function> func;
        Local<FunctionTemplate> funcTemplate;





        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "signHashedData", SignHashedData);
        Nan::SetMethod(constructor, "verifySignatureWithHashInput", VerifySignatureWithHashInput);
        Nan::SetMethod(constructor, "encrypt", Encrypt);
        Nan::SetMethod(constructor, "decrypt", Decrypt);
        Nan::SetMethod(constructor, "encryptAndAuthenticate", EncryptAndAuthenticate);
        Nan::SetMethod(constructor, "decryptAndAuthenticate", DecryptAndAuthenticate);
        Nan::SetMethod(constructor, "sign", Sign);
        Nan::SetMethod(constructor, "verifySignature", VerifySignature);
        Nan::SetMethod(constructor, "deriveKeyMaterial", DeriveKeyMaterial);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(DecryptAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("decryptAsync").ToLocalChecked(), func);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(SignAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("signAsync").ToLocalChecked(), func);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(SignHashedDataAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("signHashedDataAsync").ToLocalChecked(), func);


        Nan::Set(exports, Nan::New<String>("CryptographicEngine").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CryptographicEngine(::Windows::Security::Cryptography::Core::CryptographicEngine^ 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::Security::Cryptography::Core::CryptographicEngine^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicEngine^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::CryptographicEngine^) 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());

      CryptographicEngine *wrapperInstance = new CryptographicEngine(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::Security::Cryptography::Core::CryptographicEngine^>(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::Security::Cryptography::Core::CryptographicEngine^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::CryptographicEngine^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCryptographicEngine(winRtInstance));
    }




    static void DecryptAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      ::Windows::Foundation::IAsyncOperation<::Windows::Storage::Streams::IBuffer^>^ op;


      if (info.Length() == 4
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
            
          op = ::Windows::Security::Cryptography::Core::CryptographicEngine::DecryptAsync(arg0,arg1,arg2);
        } 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;
      }

      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Storage::Streams::IBuffer^> t)
      {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {

            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }

    static void SignAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      ::Windows::Foundation::IAsyncOperation<::Windows::Storage::Streams::IBuffer^>^ op;


      if (info.Length() == 3
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
            
          op = ::Windows::Security::Cryptography::Core::CryptographicEngine::SignAsync(arg0,arg1);
        } 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;
      }

      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Storage::Streams::IBuffer^> t)
      {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {

            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }

    static void SignHashedDataAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      ::Windows::Foundation::IAsyncOperation<::Windows::Storage::Streams::IBuffer^>^ op;


      if (info.Length() == 3
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
            
          op = ::Windows::Security::Cryptography::Core::CryptographicEngine::SignHashedDataAsync(arg0,arg1);
        } 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;
      }

      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Storage::Streams::IBuffer^> t)
      {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {

            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }


    static void SignHashedData(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::SignHashedData(arg0, arg1);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 VerifySignatureWithHashInput(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          bool result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::VerifySignatureWithHashInput(arg0, arg1, arg2);
          info.GetReturnValue().Set(Nan::New<Boolean>(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 Encrypt(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::Encrypt(arg0, arg1, arg2);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 Decrypt(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::Decrypt(arg0, arg1, arg2);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 EncryptAndAuthenticate(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 4
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[3]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
          ::Windows::Storage::Streams::IBuffer^ arg3 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[3]));
          
          ::Windows::Security::Cryptography::Core::EncryptedAndAuthenticatedData^ result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::EncryptAndAuthenticate(arg0, arg1, arg2, arg3);
          info.GetReturnValue().Set(WrapEncryptedAndAuthenticatedData(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 DecryptAndAuthenticate(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 5
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[3])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[4]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
          ::Windows::Storage::Streams::IBuffer^ arg3 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[3]));
          ::Windows::Storage::Streams::IBuffer^ arg4 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[4]));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::DecryptAndAuthenticate(arg0, arg1, arg2, arg3, arg4);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 Sign(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::Sign(arg0, arg1);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 VerifySignature(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[2]))
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Storage::Streams::IBuffer^ arg1 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Storage::Streams::IBuffer^ arg2 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          bool result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::VerifySignature(arg0, arg1, arg2);
          info.GetReturnValue().Set(Nan::New<Boolean>(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 DeriveKeyMaterial(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::CryptographicKey^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationParameters^>(info[1])
        && info[2]->IsUint32())
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicKey^ arg0 = UnwrapCryptographicKey(info[0]);
          ::Windows::Security::Cryptography::Core::KeyDerivationParameters^ arg1 = UnwrapKeyDerivationParameters(info[1]);
          unsigned int arg2 = static_cast<unsigned int>(Nan::To<uint32_t>(info[2]).FromMaybe(0));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = ::Windows::Security::Cryptography::Core::CryptographicEngine::DeriveKeyMaterial(arg0, arg1, arg2);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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::Security::Cryptography::Core::CryptographicEngine^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCryptographicEngine(::Windows::Security::Cryptography::Core::CryptographicEngine^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::CryptographicEngine^ UnwrapCryptographicEngine(Local<Value> value);
  };

  Persistent<FunctionTemplate> CryptographicEngine::s_constructorTemplate;

  v8::Local<v8::Value> WrapCryptographicEngine(::Windows::Security::Cryptography::Core::CryptographicEngine^ 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>(CryptographicEngine::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::CryptographicEngine^ UnwrapCryptographicEngine(Local<Value> value) {
     return CryptographicEngine::Unwrap<CryptographicEngine>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCryptographicEngine(Local<Object> exports) {
    CryptographicEngine::Init(exports);
  }

  class HashAlgorithmProvider : 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>("HashAlgorithmProvider").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "hashData", HashData);
            Nan::SetPrototypeMethod(localRef, "createHash", CreateHash);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("algorithmName").ToLocalChecked(), AlgorithmNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hashLength").ToLocalChecked(), HashLengthGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "openAlgorithm", OpenAlgorithm);


        Nan::Set(exports, Nan::New<String>("HashAlgorithmProvider").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      HashAlgorithmProvider(::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ 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::Security::Cryptography::Core::HashAlgorithmProvider^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::HashAlgorithmProvider^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::HashAlgorithmProvider^) 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());

      HashAlgorithmProvider *wrapperInstance = new HashAlgorithmProvider(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::Security::Cryptography::Core::HashAlgorithmProvider^>(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::Security::Cryptography::Core::HashAlgorithmProvider^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::HashAlgorithmProvider^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapHashAlgorithmProvider(winRtInstance));
    }


    static void HashData(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::HashAlgorithmProvider^>(info.This())) {
        return;
      }

      HashAlgorithmProvider *wrapper = HashAlgorithmProvider::Unwrap<HashAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Storage::Streams::IBuffer^ result;
          result = wrapper->_instance->HashData(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", 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 CreateHash(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::HashAlgorithmProvider^>(info.This())) {
        return;
      }

      HashAlgorithmProvider *wrapper = HashAlgorithmProvider::Unwrap<HashAlgorithmProvider>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Security::Cryptography::Core::CryptographicHash^ result;
          result = wrapper->_instance->CreateHash();
          info.GetReturnValue().Set(WrapCryptographicHash(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 OpenAlgorithm(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          
          ::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ result;
          result = ::Windows::Security::Cryptography::Core::HashAlgorithmProvider::OpenAlgorithm(arg0);
          info.GetReturnValue().Set(WrapHashAlgorithmProvider(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 AlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::HashAlgorithmProvider^>(info.This())) {
        return;
      }

      HashAlgorithmProvider *wrapper = HashAlgorithmProvider::Unwrap<HashAlgorithmProvider>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->AlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void HashLengthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::HashAlgorithmProvider^>(info.This())) {
        return;
      }

      HashAlgorithmProvider *wrapper = HashAlgorithmProvider::Unwrap<HashAlgorithmProvider>(info.This());

      try  {
        unsigned int result = wrapper->_instance->HashLength;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapHashAlgorithmProvider(::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ UnwrapHashAlgorithmProvider(Local<Value> value);
  };

  Persistent<FunctionTemplate> HashAlgorithmProvider::s_constructorTemplate;

  v8::Local<v8::Value> WrapHashAlgorithmProvider(::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ 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>(HashAlgorithmProvider::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::HashAlgorithmProvider^ UnwrapHashAlgorithmProvider(Local<Value> value) {
     return HashAlgorithmProvider::Unwrap<HashAlgorithmProvider>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitHashAlgorithmProvider(Local<Object> exports) {
    HashAlgorithmProvider::Init(exports);
  }

  class MacAlgorithmProvider : 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>("MacAlgorithmProvider").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "createKey", CreateKey);
            Nan::SetPrototypeMethod(localRef, "createHash", CreateHash);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("algorithmName").ToLocalChecked(), AlgorithmNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("macLength").ToLocalChecked(), MacLengthGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "openAlgorithm", OpenAlgorithm);


        Nan::Set(exports, Nan::New<String>("MacAlgorithmProvider").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      MacAlgorithmProvider(::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ 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::Security::Cryptography::Core::MacAlgorithmProvider^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::MacAlgorithmProvider^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::MacAlgorithmProvider^) 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());

      MacAlgorithmProvider *wrapperInstance = new MacAlgorithmProvider(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::Security::Cryptography::Core::MacAlgorithmProvider^>(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::Security::Cryptography::Core::MacAlgorithmProvider^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::MacAlgorithmProvider^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapMacAlgorithmProvider(winRtInstance));
    }


    static void CreateKey(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::MacAlgorithmProvider^>(info.This())) {
        return;
      }

      MacAlgorithmProvider *wrapper = MacAlgorithmProvider::Unwrap<MacAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->CreateKey(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(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 CreateHash(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::MacAlgorithmProvider^>(info.This())) {
        return;
      }

      MacAlgorithmProvider *wrapper = MacAlgorithmProvider::Unwrap<MacAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Security::Cryptography::Core::CryptographicHash^ result;
          result = wrapper->_instance->CreateHash(arg0);
          info.GetReturnValue().Set(WrapCryptographicHash(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 OpenAlgorithm(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          
          ::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ result;
          result = ::Windows::Security::Cryptography::Core::MacAlgorithmProvider::OpenAlgorithm(arg0);
          info.GetReturnValue().Set(WrapMacAlgorithmProvider(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 AlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::MacAlgorithmProvider^>(info.This())) {
        return;
      }

      MacAlgorithmProvider *wrapper = MacAlgorithmProvider::Unwrap<MacAlgorithmProvider>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->AlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void MacLengthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::MacAlgorithmProvider^>(info.This())) {
        return;
      }

      MacAlgorithmProvider *wrapper = MacAlgorithmProvider::Unwrap<MacAlgorithmProvider>(info.This());

      try  {
        unsigned int result = wrapper->_instance->MacLength;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapMacAlgorithmProvider(::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ UnwrapMacAlgorithmProvider(Local<Value> value);
  };

  Persistent<FunctionTemplate> MacAlgorithmProvider::s_constructorTemplate;

  v8::Local<v8::Value> WrapMacAlgorithmProvider(::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ 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>(MacAlgorithmProvider::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::MacAlgorithmProvider^ UnwrapMacAlgorithmProvider(Local<Value> value) {
     return MacAlgorithmProvider::Unwrap<MacAlgorithmProvider>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMacAlgorithmProvider(Local<Object> exports) {
    MacAlgorithmProvider::Init(exports);
  }

  class KeyDerivationAlgorithmProvider : 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>("KeyDerivationAlgorithmProvider").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "createKey", CreateKey);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("algorithmName").ToLocalChecked(), AlgorithmNameGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "openAlgorithm", OpenAlgorithm);


        Nan::Set(exports, Nan::New<String>("KeyDerivationAlgorithmProvider").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      KeyDerivationAlgorithmProvider(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ 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::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^) 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());

      KeyDerivationAlgorithmProvider *wrapperInstance = new KeyDerivationAlgorithmProvider(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::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^>(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::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapKeyDerivationAlgorithmProvider(winRtInstance));
    }


    static void CreateKey(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^>(info.This())) {
        return;
      }

      KeyDerivationAlgorithmProvider *wrapper = KeyDerivationAlgorithmProvider::Unwrap<KeyDerivationAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->CreateKey(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(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 OpenAlgorithm(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          
          ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ result;
          result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider::OpenAlgorithm(arg0);
          info.GetReturnValue().Set(WrapKeyDerivationAlgorithmProvider(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 AlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^>(info.This())) {
        return;
      }

      KeyDerivationAlgorithmProvider *wrapper = KeyDerivationAlgorithmProvider::Unwrap<KeyDerivationAlgorithmProvider>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->AlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapKeyDerivationAlgorithmProvider(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ UnwrapKeyDerivationAlgorithmProvider(Local<Value> value);
  };

  Persistent<FunctionTemplate> KeyDerivationAlgorithmProvider::s_constructorTemplate;

  v8::Local<v8::Value> WrapKeyDerivationAlgorithmProvider(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ 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>(KeyDerivationAlgorithmProvider::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmProvider^ UnwrapKeyDerivationAlgorithmProvider(Local<Value> value) {
     return KeyDerivationAlgorithmProvider::Unwrap<KeyDerivationAlgorithmProvider>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitKeyDerivationAlgorithmProvider(Local<Object> exports) {
    KeyDerivationAlgorithmProvider::Init(exports);
  }

  class SymmetricKeyAlgorithmProvider : 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>("SymmetricKeyAlgorithmProvider").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "createSymmetricKey", CreateSymmetricKey);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("algorithmName").ToLocalChecked(), AlgorithmNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("blockLength").ToLocalChecked(), BlockLengthGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "openAlgorithm", OpenAlgorithm);


        Nan::Set(exports, Nan::New<String>("SymmetricKeyAlgorithmProvider").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      SymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ 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::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^) 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());

      SymmetricKeyAlgorithmProvider *wrapperInstance = new SymmetricKeyAlgorithmProvider(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::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^>(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::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapSymmetricKeyAlgorithmProvider(winRtInstance));
    }


    static void CreateSymmetricKey(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      SymmetricKeyAlgorithmProvider *wrapper = SymmetricKeyAlgorithmProvider::Unwrap<SymmetricKeyAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->CreateSymmetricKey(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(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 OpenAlgorithm(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          
          ::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ result;
          result = ::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider::OpenAlgorithm(arg0);
          info.GetReturnValue().Set(WrapSymmetricKeyAlgorithmProvider(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 AlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      SymmetricKeyAlgorithmProvider *wrapper = SymmetricKeyAlgorithmProvider::Unwrap<SymmetricKeyAlgorithmProvider>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->AlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void BlockLengthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      SymmetricKeyAlgorithmProvider *wrapper = SymmetricKeyAlgorithmProvider::Unwrap<SymmetricKeyAlgorithmProvider>(info.This());

      try  {
        unsigned int result = wrapper->_instance->BlockLength;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapSymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ UnwrapSymmetricKeyAlgorithmProvider(Local<Value> value);
  };

  Persistent<FunctionTemplate> SymmetricKeyAlgorithmProvider::s_constructorTemplate;

  v8::Local<v8::Value> WrapSymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ 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>(SymmetricKeyAlgorithmProvider::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider^ UnwrapSymmetricKeyAlgorithmProvider(Local<Value> value) {
     return SymmetricKeyAlgorithmProvider::Unwrap<SymmetricKeyAlgorithmProvider>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitSymmetricKeyAlgorithmProvider(Local<Object> exports) {
    SymmetricKeyAlgorithmProvider::Init(exports);
  }

  class AsymmetricKeyAlgorithmProvider : 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>("AsymmetricKeyAlgorithmProvider").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "createKeyPair", CreateKeyPair);
            Nan::SetPrototypeMethod(localRef, "importKeyPair", ImportKeyPair);
            Nan::SetPrototypeMethod(localRef, "importPublicKey", ImportPublicKey);
            Nan::SetPrototypeMethod(localRef, "createKeyPairWithCurveName", CreateKeyPairWithCurveName);
            Nan::SetPrototypeMethod(localRef, "createKeyPairWithCurveParameters", CreateKeyPairWithCurveParameters);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("algorithmName").ToLocalChecked(), AlgorithmNameGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetMethod(constructor, "openAlgorithm", OpenAlgorithm);


        Nan::Set(exports, Nan::New<String>("AsymmetricKeyAlgorithmProvider").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      AsymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ 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::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^) 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());

      AsymmetricKeyAlgorithmProvider *wrapperInstance = new AsymmetricKeyAlgorithmProvider(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::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(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::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapAsymmetricKeyAlgorithmProvider(winRtInstance));
    }


    static void CreateKeyPair(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      AsymmetricKeyAlgorithmProvider *wrapper = AsymmetricKeyAlgorithmProvider::Unwrap<AsymmetricKeyAlgorithmProvider>(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));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->CreateKeyPair(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(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 ImportKeyPair(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      AsymmetricKeyAlgorithmProvider *wrapper = AsymmetricKeyAlgorithmProvider::Unwrap<AsymmetricKeyAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->ImportKeyPair(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(result));
          return;
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0])
        && info[1]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType arg1 = static_cast<::Windows::Security::Cryptography::Core::CryptographicPrivateKeyBlobType>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->ImportKeyPair(arg0, arg1);
          info.GetReturnValue().Set(WrapCryptographicKey(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 ImportPublicKey(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      AsymmetricKeyAlgorithmProvider *wrapper = AsymmetricKeyAlgorithmProvider::Unwrap<AsymmetricKeyAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->ImportPublicKey(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(result));
          return;
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0])
        && info[1]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType arg1 = static_cast<::Windows::Security::Cryptography::Core::CryptographicPublicKeyBlobType>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->ImportPublicKey(arg0, arg1);
          info.GetReturnValue().Set(WrapCryptographicKey(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 CreateKeyPairWithCurveName(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      AsymmetricKeyAlgorithmProvider *wrapper = AsymmetricKeyAlgorithmProvider::Unwrap<AsymmetricKeyAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->CreateKeyPairWithCurveName(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(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 CreateKeyPairWithCurveParameters(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      AsymmetricKeyAlgorithmProvider *wrapper = AsymmetricKeyAlgorithmProvider::Unwrap<AsymmetricKeyAlgorithmProvider>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Security::Cryptography::Core::CryptographicKey^ result;
          result = wrapper->_instance->CreateKeyPairWithCurveParameters(arg0);
          info.GetReturnValue().Set(WrapCryptographicKey(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 OpenAlgorithm(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          
          ::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ result;
          result = ::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider::OpenAlgorithm(arg0);
          info.GetReturnValue().Set(WrapAsymmetricKeyAlgorithmProvider(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 AlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^>(info.This())) {
        return;
      }

      AsymmetricKeyAlgorithmProvider *wrapper = AsymmetricKeyAlgorithmProvider::Unwrap<AsymmetricKeyAlgorithmProvider>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->AlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapAsymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ UnwrapAsymmetricKeyAlgorithmProvider(Local<Value> value);
  };

  Persistent<FunctionTemplate> AsymmetricKeyAlgorithmProvider::s_constructorTemplate;

  v8::Local<v8::Value> WrapAsymmetricKeyAlgorithmProvider(::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ 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>(AsymmetricKeyAlgorithmProvider::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::AsymmetricKeyAlgorithmProvider^ UnwrapAsymmetricKeyAlgorithmProvider(Local<Value> value) {
     return AsymmetricKeyAlgorithmProvider::Unwrap<AsymmetricKeyAlgorithmProvider>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAsymmetricKeyAlgorithmProvider(Local<Object> exports) {
    AsymmetricKeyAlgorithmProvider::Init(exports);
  }

  class HashAlgorithmNames : 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>("HashAlgorithmNames").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);






        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetAccessor(constructor, Nan::New<String>("md5").ToLocalChecked(), Md5Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sha1").ToLocalChecked(), Sha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sha256").ToLocalChecked(), Sha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sha384").ToLocalChecked(), Sha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sha512").ToLocalChecked(), Sha512Getter);


        Nan::Set(exports, Nan::New<String>("HashAlgorithmNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      HashAlgorithmNames(::Windows::Security::Cryptography::Core::HashAlgorithmNames^ 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::Security::Cryptography::Core::HashAlgorithmNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::HashAlgorithmNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::HashAlgorithmNames^) 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());

      HashAlgorithmNames *wrapperInstance = new HashAlgorithmNames(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::Security::Cryptography::Core::HashAlgorithmNames^>(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::Security::Cryptography::Core::HashAlgorithmNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::HashAlgorithmNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapHashAlgorithmNames(winRtInstance));
    }







    static void Md5Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::HashAlgorithmNames::Md5;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::HashAlgorithmNames::Sha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::HashAlgorithmNames::Sha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::HashAlgorithmNames::Sha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::HashAlgorithmNames::Sha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Core::HashAlgorithmNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapHashAlgorithmNames(::Windows::Security::Cryptography::Core::HashAlgorithmNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::HashAlgorithmNames^ UnwrapHashAlgorithmNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> HashAlgorithmNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapHashAlgorithmNames(::Windows::Security::Cryptography::Core::HashAlgorithmNames^ 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>(HashAlgorithmNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::HashAlgorithmNames^ UnwrapHashAlgorithmNames(Local<Value> value) {
     return HashAlgorithmNames::Unwrap<HashAlgorithmNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitHashAlgorithmNames(Local<Object> exports) {
    HashAlgorithmNames::Init(exports);
  }

  class MacAlgorithmNames : 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>("MacAlgorithmNames").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);






        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetAccessor(constructor, Nan::New<String>("aesCmac").ToLocalChecked(), AesCmacGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("hmacMd5").ToLocalChecked(), HmacMd5Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("hmacSha1").ToLocalChecked(), HmacSha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("hmacSha256").ToLocalChecked(), HmacSha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("hmacSha384").ToLocalChecked(), HmacSha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("hmacSha512").ToLocalChecked(), HmacSha512Getter);


        Nan::Set(exports, Nan::New<String>("MacAlgorithmNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      MacAlgorithmNames(::Windows::Security::Cryptography::Core::MacAlgorithmNames^ 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::Security::Cryptography::Core::MacAlgorithmNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::MacAlgorithmNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::MacAlgorithmNames^) 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());

      MacAlgorithmNames *wrapperInstance = new MacAlgorithmNames(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::Security::Cryptography::Core::MacAlgorithmNames^>(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::Security::Cryptography::Core::MacAlgorithmNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::MacAlgorithmNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapMacAlgorithmNames(winRtInstance));
    }







    static void AesCmacGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::MacAlgorithmNames::AesCmac;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void HmacMd5Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::MacAlgorithmNames::HmacMd5;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void HmacSha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::MacAlgorithmNames::HmacSha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void HmacSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::MacAlgorithmNames::HmacSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void HmacSha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::MacAlgorithmNames::HmacSha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void HmacSha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::MacAlgorithmNames::HmacSha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Core::MacAlgorithmNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapMacAlgorithmNames(::Windows::Security::Cryptography::Core::MacAlgorithmNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::MacAlgorithmNames^ UnwrapMacAlgorithmNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> MacAlgorithmNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapMacAlgorithmNames(::Windows::Security::Cryptography::Core::MacAlgorithmNames^ 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>(MacAlgorithmNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::MacAlgorithmNames^ UnwrapMacAlgorithmNames(Local<Value> value) {
     return MacAlgorithmNames::Unwrap<MacAlgorithmNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMacAlgorithmNames(Local<Object> exports) {
    MacAlgorithmNames::Init(exports);
  }

  class SymmetricAlgorithmNames : 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>("SymmetricAlgorithmNames").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);






        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetAccessor(constructor, Nan::New<String>("aesCbc").ToLocalChecked(), AesCbcGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("aesCbcPkcs7").ToLocalChecked(), AesCbcPkcs7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("aesCcm").ToLocalChecked(), AesCcmGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("aesEcb").ToLocalChecked(), AesEcbGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("aesEcbPkcs7").ToLocalChecked(), AesEcbPkcs7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("aesGcm").ToLocalChecked(), AesGcmGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("desCbc").ToLocalChecked(), DesCbcGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("desCbcPkcs7").ToLocalChecked(), DesCbcPkcs7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("desEcb").ToLocalChecked(), DesEcbGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("desEcbPkcs7").ToLocalChecked(), DesEcbPkcs7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rc2Cbc").ToLocalChecked(), Rc2CbcGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("rc2CbcPkcs7").ToLocalChecked(), Rc2CbcPkcs7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rc2Ecb").ToLocalChecked(), Rc2EcbGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("rc2EcbPkcs7").ToLocalChecked(), Rc2EcbPkcs7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rc4").ToLocalChecked(), Rc4Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("tripleDesCbc").ToLocalChecked(), TripleDesCbcGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("tripleDesCbcPkcs7").ToLocalChecked(), TripleDesCbcPkcs7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("tripleDesEcb").ToLocalChecked(), TripleDesEcbGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("tripleDesEcbPkcs7").ToLocalChecked(), TripleDesEcbPkcs7Getter);


        Nan::Set(exports, Nan::New<String>("SymmetricAlgorithmNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      SymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ 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::Security::Cryptography::Core::SymmetricAlgorithmNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^) 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());

      SymmetricAlgorithmNames *wrapperInstance = new SymmetricAlgorithmNames(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::Security::Cryptography::Core::SymmetricAlgorithmNames^>(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::Security::Cryptography::Core::SymmetricAlgorithmNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapSymmetricAlgorithmNames(winRtInstance));
    }







    static void AesCbcGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::AesCbc;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void AesCbcPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::AesCbcPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void AesCcmGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::AesCcm;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void AesEcbGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::AesEcb;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void AesEcbPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::AesEcbPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void AesGcmGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::AesGcm;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void DesCbcGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::DesCbc;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void DesCbcPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::DesCbcPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void DesEcbGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::DesEcb;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void DesEcbPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::DesEcbPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Rc2CbcGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::Rc2Cbc;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Rc2CbcPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::Rc2CbcPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Rc2EcbGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::Rc2Ecb;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Rc2EcbPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::Rc2EcbPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Rc4Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::Rc4;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void TripleDesCbcGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::TripleDesCbc;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void TripleDesCbcPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::TripleDesCbcPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void TripleDesEcbGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::TripleDesEcb;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void TripleDesEcbPkcs7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames::TripleDesEcbPkcs7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapSymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ UnwrapSymmetricAlgorithmNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> SymmetricAlgorithmNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapSymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ 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>(SymmetricAlgorithmNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::SymmetricAlgorithmNames^ UnwrapSymmetricAlgorithmNames(Local<Value> value) {
     return SymmetricAlgorithmNames::Unwrap<SymmetricAlgorithmNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitSymmetricAlgorithmNames(Local<Object> exports) {
    SymmetricAlgorithmNames::Init(exports);
  }

  class AsymmetricAlgorithmNames : 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>("AsymmetricAlgorithmNames").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);






        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetAccessor(constructor, Nan::New<String>("ecdsaP521Sha512").ToLocalChecked(), EcdsaP521Sha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("dsaSha1").ToLocalChecked(), DsaSha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("dsaSha256").ToLocalChecked(), DsaSha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsaP256Sha256").ToLocalChecked(), EcdsaP256Sha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsaP384Sha384").ToLocalChecked(), EcdsaP384Sha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPkcs1Sha256").ToLocalChecked(), RsaSignPkcs1Sha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaOaepSha1").ToLocalChecked(), RsaOaepSha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaOaepSha256").ToLocalChecked(), RsaOaepSha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaOaepSha384").ToLocalChecked(), RsaOaepSha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaOaepSha512").ToLocalChecked(), RsaOaepSha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaPkcs1").ToLocalChecked(), RsaPkcs1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPkcs1Sha1").ToLocalChecked(), RsaSignPkcs1Sha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPkcs1Sha384").ToLocalChecked(), RsaSignPkcs1Sha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPkcs1Sha512").ToLocalChecked(), RsaSignPkcs1Sha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPssSha1").ToLocalChecked(), RsaSignPssSha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPssSha256").ToLocalChecked(), RsaSignPssSha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPssSha384").ToLocalChecked(), RsaSignPssSha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsaSignPssSha512").ToLocalChecked(), RsaSignPssSha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsaSha384").ToLocalChecked(), EcdsaSha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsaSha512").ToLocalChecked(), EcdsaSha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsaSha256").ToLocalChecked(), EcdsaSha256Getter);


        Nan::Set(exports, Nan::New<String>("AsymmetricAlgorithmNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      AsymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ 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::Security::Cryptography::Core::AsymmetricAlgorithmNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^) 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());

      AsymmetricAlgorithmNames *wrapperInstance = new AsymmetricAlgorithmNames(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::Security::Cryptography::Core::AsymmetricAlgorithmNames^>(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::Security::Cryptography::Core::AsymmetricAlgorithmNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapAsymmetricAlgorithmNames(winRtInstance));
    }







    static void EcdsaP521Sha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::EcdsaP521Sha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void DsaSha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::DsaSha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void DsaSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::DsaSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void EcdsaP256Sha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::EcdsaP256Sha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void EcdsaP384Sha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::EcdsaP384Sha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPkcs1Sha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPkcs1Sha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaOaepSha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaOaepSha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaOaepSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaOaepSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaOaepSha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaOaepSha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaOaepSha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaOaepSha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaPkcs1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaPkcs1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPkcs1Sha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPkcs1Sha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPkcs1Sha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPkcs1Sha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPkcs1Sha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPkcs1Sha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPssSha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPssSha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPssSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPssSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPssSha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPssSha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaSignPssSha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::RsaSignPssSha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void EcdsaSha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::EcdsaSha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void EcdsaSha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::EcdsaSha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void EcdsaSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames::EcdsaSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapAsymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ UnwrapAsymmetricAlgorithmNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> AsymmetricAlgorithmNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapAsymmetricAlgorithmNames(::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ 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>(AsymmetricAlgorithmNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::AsymmetricAlgorithmNames^ UnwrapAsymmetricAlgorithmNames(Local<Value> value) {
     return AsymmetricAlgorithmNames::Unwrap<AsymmetricAlgorithmNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAsymmetricAlgorithmNames(Local<Object> exports) {
    AsymmetricAlgorithmNames::Init(exports);
  }

  class EccCurveNames : 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>("EccCurveNames").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);






        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetAccessor(constructor, Nan::New<String>("allEccCurveNames").ToLocalChecked(), AllEccCurveNamesGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP160r1").ToLocalChecked(), BrainpoolP160r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP160t1").ToLocalChecked(), BrainpoolP160t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP192r1").ToLocalChecked(), BrainpoolP192r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP192t1").ToLocalChecked(), BrainpoolP192t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP224r1").ToLocalChecked(), BrainpoolP224r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP224t1").ToLocalChecked(), BrainpoolP224t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP256r1").ToLocalChecked(), BrainpoolP256r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP256t1").ToLocalChecked(), BrainpoolP256t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP320r1").ToLocalChecked(), BrainpoolP320r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP320t1").ToLocalChecked(), BrainpoolP320t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP384r1").ToLocalChecked(), BrainpoolP384r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP384t1").ToLocalChecked(), BrainpoolP384t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP512r1").ToLocalChecked(), BrainpoolP512r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("brainpoolP512t1").ToLocalChecked(), BrainpoolP512t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("curve25519").ToLocalChecked(), Curve25519Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ec192wapi").ToLocalChecked(), Ec192wapiGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("nistP192").ToLocalChecked(), NistP192Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("nistP224").ToLocalChecked(), NistP224Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("nistP256").ToLocalChecked(), NistP256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("nistP384").ToLocalChecked(), NistP384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("nistP521").ToLocalChecked(), NistP521Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("numsP256t1").ToLocalChecked(), NumsP256t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("numsP384t1").ToLocalChecked(), NumsP384t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("numsP512t1").ToLocalChecked(), NumsP512t1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP160k1").ToLocalChecked(), SecP160k1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP160r1").ToLocalChecked(), SecP160r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP160r2").ToLocalChecked(), SecP160r2Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP192k1").ToLocalChecked(), SecP192k1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP192r1").ToLocalChecked(), SecP192r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP224k1").ToLocalChecked(), SecP224k1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP224r1").ToLocalChecked(), SecP224r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP256k1").ToLocalChecked(), SecP256k1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP256r1").ToLocalChecked(), SecP256r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP384r1").ToLocalChecked(), SecP384r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("secP521r1").ToLocalChecked(), SecP521r1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("wtls12").ToLocalChecked(), Wtls12Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("wtls7").ToLocalChecked(), Wtls7Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("wtls9").ToLocalChecked(), Wtls9Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("x962P192v1").ToLocalChecked(), X962P192v1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("x962P192v2").ToLocalChecked(), X962P192v2Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("x962P192v3").ToLocalChecked(), X962P192v3Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("x962P239v1").ToLocalChecked(), X962P239v1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("x962P239v2").ToLocalChecked(), X962P239v2Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("x962P239v3").ToLocalChecked(), X962P239v3Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("x962P256v1").ToLocalChecked(), X962P256v1Getter);


        Nan::Set(exports, Nan::New<String>("EccCurveNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      EccCurveNames(::Windows::Security::Cryptography::Core::EccCurveNames^ 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::Security::Cryptography::Core::EccCurveNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::EccCurveNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::EccCurveNames^) 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());

      EccCurveNames *wrapperInstance = new EccCurveNames(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::Security::Cryptography::Core::EccCurveNames^>(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::Security::Cryptography::Core::EccCurveNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::EccCurveNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapEccCurveNames(winRtInstance));
    }







    static void AllEccCurveNamesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::AllEccCurveNames;
        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(v8::Isolate::GetCurrent(), value)));
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP160r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP160r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP160t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP160t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP192r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP192r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP192t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP192t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP224r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP224r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP224t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP224t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP256r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP256r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP256t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP256t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP320r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP320r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP320t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP320t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP384r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP384r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP384t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP384t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP512r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP512r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void BrainpoolP512t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::BrainpoolP512t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Curve25519Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::Curve25519;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Ec192wapiGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::Ec192wapi;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NistP192Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NistP192;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NistP224Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NistP224;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NistP256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NistP256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NistP384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NistP384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NistP521Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NistP521;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NumsP256t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NumsP256t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NumsP384t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NumsP384t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void NumsP512t1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::NumsP512t1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP160k1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP160k1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP160r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP160r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP160r2Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP160r2;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP192k1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP192k1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP192r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP192r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP224k1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP224k1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP224r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP224r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP256k1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP256k1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP256r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP256r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP384r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP384r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SecP521r1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::SecP521r1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Wtls12Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::Wtls12;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Wtls7Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::Wtls7;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Wtls9Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::Wtls9;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void X962P192v1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::X962P192v1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void X962P192v2Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::X962P192v2;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void X962P192v3Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::X962P192v3;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void X962P239v1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::X962P239v1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void X962P239v2Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::X962P239v2;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void X962P239v3Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::X962P239v3;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void X962P256v1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::EccCurveNames::X962P256v1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Core::EccCurveNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapEccCurveNames(::Windows::Security::Cryptography::Core::EccCurveNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::EccCurveNames^ UnwrapEccCurveNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> EccCurveNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapEccCurveNames(::Windows::Security::Cryptography::Core::EccCurveNames^ 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>(EccCurveNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::EccCurveNames^ UnwrapEccCurveNames(Local<Value> value) {
     return EccCurveNames::Unwrap<EccCurveNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitEccCurveNames(Local<Object> exports) {
    EccCurveNames::Init(exports);
  }

  class KeyDerivationAlgorithmNames : 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>("KeyDerivationAlgorithmNames").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);






        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        Nan::SetAccessor(constructor, Nan::New<String>("pbkdf2Sha256").ToLocalChecked(), Pbkdf2Sha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("pbkdf2Md5").ToLocalChecked(), Pbkdf2Md5Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("pbkdf2Sha1").ToLocalChecked(), Pbkdf2Sha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp800108CtrHmacSha512").ToLocalChecked(), Sp800108CtrHmacSha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("pbkdf2Sha384").ToLocalChecked(), Pbkdf2Sha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("pbkdf2Sha512").ToLocalChecked(), Pbkdf2Sha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp800108CtrHmacMd5").ToLocalChecked(), Sp800108CtrHmacMd5Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp800108CtrHmacSha1").ToLocalChecked(), Sp800108CtrHmacSha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp800108CtrHmacSha256").ToLocalChecked(), Sp800108CtrHmacSha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp800108CtrHmacSha384").ToLocalChecked(), Sp800108CtrHmacSha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp80056aConcatMd5").ToLocalChecked(), Sp80056aConcatMd5Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp80056aConcatSha1").ToLocalChecked(), Sp80056aConcatSha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp80056aConcatSha256").ToLocalChecked(), Sp80056aConcatSha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp80056aConcatSha384").ToLocalChecked(), Sp80056aConcatSha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("sp80056aConcatSha512").ToLocalChecked(), Sp80056aConcatSha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("capiKdfSha1").ToLocalChecked(), CapiKdfSha1Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("capiKdfSha256").ToLocalChecked(), CapiKdfSha256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("capiKdfSha384").ToLocalChecked(), CapiKdfSha384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("capiKdfSha512").ToLocalChecked(), CapiKdfSha512Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("capiKdfMd5").ToLocalChecked(), CapiKdfMd5Getter);


        Nan::Set(exports, Nan::New<String>("KeyDerivationAlgorithmNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      KeyDerivationAlgorithmNames(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ 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::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^) 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());

      KeyDerivationAlgorithmNames *wrapperInstance = new KeyDerivationAlgorithmNames(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::Security::Cryptography::Core::KeyDerivationAlgorithmNames^>(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::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapKeyDerivationAlgorithmNames(winRtInstance));
    }







    static void Pbkdf2Sha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Pbkdf2Sha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Pbkdf2Md5Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Pbkdf2Md5;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Pbkdf2Sha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Pbkdf2Sha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp800108CtrHmacSha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp800108CtrHmacSha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Pbkdf2Sha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Pbkdf2Sha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Pbkdf2Sha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Pbkdf2Sha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp800108CtrHmacMd5Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp800108CtrHmacMd5;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp800108CtrHmacSha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp800108CtrHmacSha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp800108CtrHmacSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp800108CtrHmacSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp800108CtrHmacSha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp800108CtrHmacSha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp80056aConcatMd5Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp80056aConcatMd5;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp80056aConcatSha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp80056aConcatSha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp80056aConcatSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp80056aConcatSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp80056aConcatSha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp80056aConcatSha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Sp80056aConcatSha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::Sp80056aConcatSha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void CapiKdfSha1Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::CapiKdfSha1;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void CapiKdfSha256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::CapiKdfSha256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void CapiKdfSha384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::CapiKdfSha384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void CapiKdfSha512Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::CapiKdfSha512;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void CapiKdfMd5Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames::CapiKdfMd5;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapKeyDerivationAlgorithmNames(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ UnwrapKeyDerivationAlgorithmNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> KeyDerivationAlgorithmNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapKeyDerivationAlgorithmNames(::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ 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>(KeyDerivationAlgorithmNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Core::KeyDerivationAlgorithmNames^ UnwrapKeyDerivationAlgorithmNames(Local<Value> value) {
     return KeyDerivationAlgorithmNames::Unwrap<KeyDerivationAlgorithmNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitKeyDerivationAlgorithmNames(Local<Object> exports) {
    KeyDerivationAlgorithmNames::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::Security::Cryptography::Core::InitCryptographicPrivateKeyBlobTypeEnum(target);
      NodeRT::Windows::Security::Cryptography::Core::InitCryptographicPublicKeyBlobTypeEnum(target);
      NodeRT::Windows::Security::Cryptography::Core::InitCapi1KdfTargetAlgorithmEnum(target);
      NodeRT::Windows::Security::Cryptography::Core::InitCryptographicPaddingEnum(target);
      NodeRT::Windows::Security::Cryptography::Core::InitKeyDerivationParameters(target);
      NodeRT::Windows::Security::Cryptography::Core::InitCryptographicKey(target);
      NodeRT::Windows::Security::Cryptography::Core::InitCryptographicHash(target);
      NodeRT::Windows::Security::Cryptography::Core::InitPersistedKeyProvider(target);
      NodeRT::Windows::Security::Cryptography::Core::InitEncryptedAndAuthenticatedData(target);
      NodeRT::Windows::Security::Cryptography::Core::InitCryptographicEngine(target);
      NodeRT::Windows::Security::Cryptography::Core::InitHashAlgorithmProvider(target);
      NodeRT::Windows::Security::Cryptography::Core::InitMacAlgorithmProvider(target);
      NodeRT::Windows::Security::Cryptography::Core::InitKeyDerivationAlgorithmProvider(target);
      NodeRT::Windows::Security::Cryptography::Core::InitSymmetricKeyAlgorithmProvider(target);
      NodeRT::Windows::Security::Cryptography::Core::InitAsymmetricKeyAlgorithmProvider(target);
      NodeRT::Windows::Security::Cryptography::Core::InitHashAlgorithmNames(target);
      NodeRT::Windows::Security::Cryptography::Core::InitMacAlgorithmNames(target);
      NodeRT::Windows::Security::Cryptography::Core::InitSymmetricAlgorithmNames(target);
      NodeRT::Windows::Security::Cryptography::Core::InitAsymmetricAlgorithmNames(target);
      NodeRT::Windows::Security::Cryptography::Core::InitEccCurveNames(target);
      NodeRT::Windows::Security::Cryptography::Core::InitKeyDerivationAlgorithmNames(target);


  NodeRT::Utils::RegisterNameSpace("Windows.Security.Cryptography.Core", target);
}



NODE_MODULE(binding, init)
