// 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 Certificates { 
  v8::Local<v8::Value> WrapCertificate(::Windows::Security::Cryptography::Certificates::Certificate^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::Certificate^ UnwrapCertificate(Local<Value> value);
  
  v8::Local<v8::Value> WrapCertificateRequestProperties(::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ UnwrapCertificateRequestProperties(Local<Value> value);
  
  v8::Local<v8::Value> WrapUserCertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ UnwrapUserCertificateEnrollmentManager(Local<Value> value);
  
  v8::Local<v8::Value> WrapPfxImportParameters(::Windows::Security::Cryptography::Certificates::PfxImportParameters^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::PfxImportParameters^ UnwrapPfxImportParameters(Local<Value> value);
  
  v8::Local<v8::Value> WrapCertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ UnwrapCertificateEnrollmentManager(Local<Value> value);
  
  v8::Local<v8::Value> WrapKeyAttestationHelper(::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ UnwrapKeyAttestationHelper(Local<Value> value);
  
  v8::Local<v8::Value> WrapCertificateQuery(::Windows::Security::Cryptography::Certificates::CertificateQuery^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CertificateQuery^ UnwrapCertificateQuery(Local<Value> value);
  
  v8::Local<v8::Value> WrapCertificateStore(::Windows::Security::Cryptography::Certificates::CertificateStore^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CertificateStore^ UnwrapCertificateStore(Local<Value> value);
  
  v8::Local<v8::Value> WrapUserCertificateStore(::Windows::Security::Cryptography::Certificates::UserCertificateStore^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::UserCertificateStore^ UnwrapUserCertificateStore(Local<Value> value);
  
  v8::Local<v8::Value> WrapCertificateStores(::Windows::Security::Cryptography::Certificates::CertificateStores^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CertificateStores^ UnwrapCertificateStores(Local<Value> value);
  
  v8::Local<v8::Value> WrapStandardCertificateStoreNames(::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ UnwrapStandardCertificateStoreNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapKeyAlgorithmNames(::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ UnwrapKeyAlgorithmNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapKeyStorageProviderNames(::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ UnwrapKeyStorageProviderNames(Local<Value> value);
  
  v8::Local<v8::Value> WrapChainBuildingParameters(::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ UnwrapChainBuildingParameters(Local<Value> value);
  
  v8::Local<v8::Value> WrapChainValidationParameters(::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ UnwrapChainValidationParameters(Local<Value> value);
  
  v8::Local<v8::Value> WrapCertificateChain(::Windows::Security::Cryptography::Certificates::CertificateChain^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CertificateChain^ UnwrapCertificateChain(Local<Value> value);
  
  v8::Local<v8::Value> WrapCertificateKeyUsages(::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ UnwrapCertificateKeyUsages(Local<Value> value);
  
  v8::Local<v8::Value> WrapSubjectAlternativeNameInfo(::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ UnwrapSubjectAlternativeNameInfo(Local<Value> value);
  
  v8::Local<v8::Value> WrapCmsTimestampInfo(::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ UnwrapCmsTimestampInfo(Local<Value> value);
  
  v8::Local<v8::Value> WrapCmsSignerInfo(::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ UnwrapCmsSignerInfo(Local<Value> value);
  
  v8::Local<v8::Value> WrapCmsAttachedSignature(::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ UnwrapCmsAttachedSignature(Local<Value> value);
  
  v8::Local<v8::Value> WrapCmsDetachedSignature(::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ wintRtInstance);
  ::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ UnwrapCmsDetachedSignature(Local<Value> value);
  



  static void InitEnrollKeyUsagesEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("EnrollKeyUsages").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("none").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::EnrollKeyUsages::None)));
    Nan::Set(enumObject, Nan::New<String>("decryption").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::EnrollKeyUsages::Decryption)));
    Nan::Set(enumObject, Nan::New<String>("signing").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::EnrollKeyUsages::Signing)));
    Nan::Set(enumObject, Nan::New<String>("keyAgreement").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::EnrollKeyUsages::KeyAgreement)));
    Nan::Set(enumObject, Nan::New<String>("all").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::EnrollKeyUsages::All)));
  }

  static void InitKeyProtectionLevelEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("KeyProtectionLevel").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("noConsent").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::KeyProtectionLevel::NoConsent)));
    Nan::Set(enumObject, Nan::New<String>("consentOnly").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::KeyProtectionLevel::ConsentOnly)));
    Nan::Set(enumObject, Nan::New<String>("consentWithPassword").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::KeyProtectionLevel::ConsentWithPassword)));
    Nan::Set(enumObject, Nan::New<String>("consentWithFingerprint").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::KeyProtectionLevel::ConsentWithFingerprint)));
  }

  static void InitExportOptionEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("ExportOption").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("notExportable").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ExportOption::NotExportable)));
    Nan::Set(enumObject, Nan::New<String>("exportable").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ExportOption::Exportable)));
  }

  static void InitKeySizeEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("KeySize").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("invalid").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::KeySize::Invalid)));
    Nan::Set(enumObject, Nan::New<String>("rsa2048").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::KeySize::Rsa2048)));
    Nan::Set(enumObject, Nan::New<String>("rsa4096").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::KeySize::Rsa4096)));
  }

  static void InitInstallOptionsEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("InstallOptions").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("none").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::InstallOptions::None)));
    Nan::Set(enumObject, Nan::New<String>("deleteExpired").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::InstallOptions::DeleteExpired)));
  }

  static void InitCertificateChainPolicyEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("CertificateChainPolicy").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("base").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::CertificateChainPolicy::Base)));
    Nan::Set(enumObject, Nan::New<String>("ssl").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::CertificateChainPolicy::Ssl)));
    Nan::Set(enumObject, Nan::New<String>("nTAuthentication").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::CertificateChainPolicy::NTAuthentication)));
    Nan::Set(enumObject, Nan::New<String>("microsoftRoot").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::CertificateChainPolicy::MicrosoftRoot)));
  }

  static void InitChainValidationResultEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("ChainValidationResult").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("success").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::Success)));
    Nan::Set(enumObject, Nan::New<String>("untrusted").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::Untrusted)));
    Nan::Set(enumObject, Nan::New<String>("revoked").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::Revoked)));
    Nan::Set(enumObject, Nan::New<String>("expired").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::Expired)));
    Nan::Set(enumObject, Nan::New<String>("incompleteChain").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::IncompleteChain)));
    Nan::Set(enumObject, Nan::New<String>("invalidSignature").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::InvalidSignature)));
    Nan::Set(enumObject, Nan::New<String>("wrongUsage").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::WrongUsage)));
    Nan::Set(enumObject, Nan::New<String>("invalidName").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::InvalidName)));
    Nan::Set(enumObject, Nan::New<String>("invalidCertificateAuthorityPolicy").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::InvalidCertificateAuthorityPolicy)));
    Nan::Set(enumObject, Nan::New<String>("basicConstraintsError").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::BasicConstraintsError)));
    Nan::Set(enumObject, Nan::New<String>("unknownCriticalExtension").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::UnknownCriticalExtension)));
    Nan::Set(enumObject, Nan::New<String>("revocationInformationMissing").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::RevocationInformationMissing)));
    Nan::Set(enumObject, Nan::New<String>("revocationFailure").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::RevocationFailure)));
    Nan::Set(enumObject, Nan::New<String>("otherErrors").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::ChainValidationResult::OtherErrors)));
  }

  static void InitSignatureValidationResultEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("SignatureValidationResult").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("success").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::SignatureValidationResult::Success)));
    Nan::Set(enumObject, Nan::New<String>("invalidParameter").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::SignatureValidationResult::InvalidParameter)));
    Nan::Set(enumObject, Nan::New<String>("badMessage").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::SignatureValidationResult::BadMessage)));
    Nan::Set(enumObject, Nan::New<String>("invalidSignature").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::SignatureValidationResult::InvalidSignature)));
    Nan::Set(enumObject, Nan::New<String>("otherErrors").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Security::Cryptography::Certificates::SignatureValidationResult::OtherErrors)));
  }



  class Certificate : 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>("Certificate").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);

        Local<Function> func;
        Local<FunctionTemplate> funcTemplate;

          
            Nan::SetPrototypeMethod(localRef, "getHashValue", GetHashValue);
            Nan::SetPrototypeMethod(localRef, "getCertificateBlob", GetCertificateBlob);
          

          
            Nan::SetPrototypeMethod(localRef, "buildChainAsync", BuildChainAsync);
          


          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("friendlyName").ToLocalChecked(), FriendlyNameGetter, FriendlyNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("enhancedKeyUsages").ToLocalChecked(), EnhancedKeyUsagesGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hasPrivateKey").ToLocalChecked(), HasPrivateKeyGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isStronglyProtected").ToLocalChecked(), IsStronglyProtectedGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("issuer").ToLocalChecked(), IssuerGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("serialNumber").ToLocalChecked(), SerialNumberGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("subject").ToLocalChecked(), SubjectGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("validFrom").ToLocalChecked(), ValidFromGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("validTo").ToLocalChecked(), ValidToGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isSecurityDeviceBound").ToLocalChecked(), IsSecurityDeviceBoundGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyAlgorithmName").ToLocalChecked(), KeyAlgorithmNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyUsages").ToLocalChecked(), KeyUsagesGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("signatureAlgorithmName").ToLocalChecked(), SignatureAlgorithmNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("signatureHashAlgorithmName").ToLocalChecked(), SignatureHashAlgorithmNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("subjectAlternativeName").ToLocalChecked(), SubjectAlternativeNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isPerUser").ToLocalChecked(), IsPerUserGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyStorageProviderName").ToLocalChecked(), KeyStorageProviderNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("storeName").ToLocalChecked(), StoreNameGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("Certificate").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      Certificate(::Windows::Security::Cryptography::Certificates::Certificate^ 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::Certificates::Certificate^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::Certificate^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 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]));
          
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::Certificate(arg0);
        } 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());

      Certificate *wrapperInstance = new Certificate(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::Certificates::Certificate^>(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::Certificates::Certificate^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::Certificate^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificate(winRtInstance));
    }

    static void BuildChainAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Security::Cryptography::Certificates::CertificateChain^>^ op;


      if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Security::Cryptography::Certificates::Certificate^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
                   return UnwrapCertificate(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          op = wrapper->_instance->BuildChainAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 3
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(info[0]) || info[0]->IsArray())
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info[1]))
      {
        try
        {
          ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Security::Cryptography::Certificates::Certificate^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
                   return UnwrapCertificate(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ arg1 = UnwrapChainBuildingParameters(info[1]);
          
          op = wrapper->_instance->BuildChainAsync(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::Security::Cryptography::Certificates::CertificateChain^> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = WrapCertificateChain(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 GetHashValue(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Platform::Array<unsigned char>^ result;
          result = wrapper->_instance->GetHashValue();
          info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<unsigned char>::CreateArrayWrapper(result, 
            [](unsigned char val) -> Local<Value> {
              return Nan::New<Integer>(val);
            },
            [](Local<Value> value) -> bool {
              return value->IsInt32();
            },
            [](Local<Value> value) -> unsigned char {
              return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
            }
          ));
          return;
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          
          ::Platform::Array<unsigned char>^ result;
          result = wrapper->_instance->GetHashValue(arg0);
          info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<unsigned char>::CreateArrayWrapper(result, 
            [](unsigned char val) -> Local<Value> {
              return Nan::New<Integer>(val);
            },
            [](Local<Value> value) -> bool {
              return value->IsInt32();
            },
            [](Local<Value> value) -> unsigned char {
              return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
            }
          ));
          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 GetCertificateBlob(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ result;
          result = wrapper->_instance->GetCertificateBlob();
          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 FriendlyNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->FriendlyName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void FriendlyNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->FriendlyName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void EnhancedKeyUsagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->EnhancedKeyUsages;
        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 HasPrivateKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        bool result = wrapper->_instance->HasPrivateKey;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IsStronglyProtectedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        bool result = wrapper->_instance->IsStronglyProtected;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IssuerGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->Issuer;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SerialNumberGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->SerialNumber;
        info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<unsigned char>::CreateArrayWrapper(result, 
            [](unsigned char val) -> Local<Value> {
              return Nan::New<Integer>(val);
            },
            [](Local<Value> value) -> bool {
              return value->IsInt32();
            },
            [](Local<Value> value) -> unsigned char {
              return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SubjectGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->Subject;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ValidFromGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        ::Windows::Foundation::DateTime result = wrapper->_instance->ValidFrom;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ValidToGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        ::Windows::Foundation::DateTime result = wrapper->_instance->ValidTo;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IsSecurityDeviceBoundGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        bool result = wrapper->_instance->IsSecurityDeviceBound;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyAlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->KeyAlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyUsagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ result = wrapper->_instance->KeyUsages;
        info.GetReturnValue().Set(WrapCertificateKeyUsages(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SignatureAlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->SignatureAlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SignatureHashAlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->SignatureHashAlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SubjectAlternativeNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ result = wrapper->_instance->SubjectAlternativeName;
        info.GetReturnValue().Set(WrapSubjectAlternativeNameInfo(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IsPerUserGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        bool result = wrapper->_instance->IsPerUser;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyStorageProviderNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->KeyStorageProviderName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void StoreNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info.This())) {
        return;
      }

      Certificate *wrapper = Certificate::Unwrap<Certificate>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->StoreName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::Certificate^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificate(::Windows::Security::Cryptography::Certificates::Certificate^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::Certificate^ UnwrapCertificate(Local<Value> value);
  };

  Persistent<FunctionTemplate> Certificate::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificate(::Windows::Security::Cryptography::Certificates::Certificate^ 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>(Certificate::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::Certificate^ UnwrapCertificate(Local<Value> value) {
     return Certificate::Unwrap<Certificate>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificate(Local<Object> exports) {
    Certificate::Init(exports);
  }

  class CertificateRequestProperties : 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>("CertificateRequestProperties").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("subject").ToLocalChecked(), SubjectGetter, SubjectSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyUsages").ToLocalChecked(), KeyUsagesGetter, KeyUsagesSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyStorageProviderName").ToLocalChecked(), KeyStorageProviderNameGetter, KeyStorageProviderNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keySize").ToLocalChecked(), KeySizeGetter, KeySizeSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("exportable").ToLocalChecked(), ExportableGetter, ExportableSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyAlgorithmName").ToLocalChecked(), KeyAlgorithmNameGetter, KeyAlgorithmNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("friendlyName").ToLocalChecked(), FriendlyNameGetter, FriendlyNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyProtectionLevel").ToLocalChecked(), KeyProtectionLevelGetter, KeyProtectionLevelSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hashAlgorithmName").ToLocalChecked(), HashAlgorithmNameGetter, HashAlgorithmNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("smartcardReaderName").ToLocalChecked(), SmartcardReaderNameGetter, SmartcardReaderNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("signingCertificate").ToLocalChecked(), SigningCertificateGetter, SigningCertificateSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("attestationCredentialCertificate").ToLocalChecked(), AttestationCredentialCertificateGetter, AttestationCredentialCertificateSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("useExistingKey").ToLocalChecked(), UseExistingKeyGetter, UseExistingKeySetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("curveParameters").ToLocalChecked(), CurveParametersGetter, CurveParametersSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("curveName").ToLocalChecked(), CurveNameGetter, CurveNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("containerNamePrefix").ToLocalChecked(), ContainerNamePrefixGetter, ContainerNamePrefixSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("containerName").ToLocalChecked(), ContainerNameGetter, ContainerNameSetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CertificateRequestProperties").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CertificateRequestProperties(::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ 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::Certificates::CertificateRequestProperties^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::CertificateRequestProperties();
        } 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());

      CertificateRequestProperties *wrapperInstance = new CertificateRequestProperties(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::Certificates::CertificateRequestProperties^>(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::Certificates::CertificateRequestProperties^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificateRequestProperties(winRtInstance));
    }





    static void SubjectGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->Subject;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SubjectSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->Subject = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyUsagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::EnrollKeyUsages result = wrapper->_instance->KeyUsages;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyUsagesSetter(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::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::EnrollKeyUsages winRtValue = static_cast<::Windows::Security::Cryptography::Certificates::EnrollKeyUsages>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->KeyUsages = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyStorageProviderNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->KeyStorageProviderName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyStorageProviderNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->KeyStorageProviderName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeySizeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(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;
      }
    }
      
    static void KeySizeSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsUint32()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->KeySize = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ExportableGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::ExportOption result = wrapper->_instance->Exportable;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ExportableSetter(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::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::ExportOption winRtValue = static_cast<::Windows::Security::Cryptography::Certificates::ExportOption>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Exportable = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyAlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->KeyAlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyAlgorithmNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->KeyAlgorithmName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void FriendlyNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->FriendlyName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void FriendlyNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->FriendlyName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyProtectionLevelGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel result = wrapper->_instance->KeyProtectionLevel;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyProtectionLevelSetter(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::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel winRtValue = static_cast<::Windows::Security::Cryptography::Certificates::KeyProtectionLevel>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->KeyProtectionLevel = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void HashAlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->HashAlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void HashAlgorithmNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->HashAlgorithmName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void SmartcardReaderNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->SmartcardReaderName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SmartcardReaderNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->SmartcardReaderName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void SigningCertificateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::Certificate^ result = wrapper->_instance->SigningCertificate;
        info.GetReturnValue().Set(WrapCertificate(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SigningCertificateSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value)) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::Certificate^ winRtValue = dynamic_cast<::Windows::Security::Cryptography::Certificates::Certificate^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->SigningCertificate = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void AttestationCredentialCertificateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::Certificate^ result = wrapper->_instance->AttestationCredentialCertificate;
        info.GetReturnValue().Set(WrapCertificate(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void AttestationCredentialCertificateSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value)) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::Certificate^ winRtValue = dynamic_cast<::Windows::Security::Cryptography::Certificates::Certificate^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->AttestationCredentialCertificate = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void UseExistingKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        bool result = wrapper->_instance->UseExistingKey;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void UseExistingKeySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->UseExistingKey = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void CurveParametersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->CurveParameters;
        info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<unsigned char>::CreateArrayWrapper(result, 
            [](unsigned char val) -> Local<Value> {
              return Nan::New<Integer>(val);
            },
            [](Local<Value> value) -> bool {
              return value->IsInt32();
            },
            [](Local<Value> value) -> unsigned char {
              return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void CurveParametersSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!(NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(value) || value->IsArray())) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        ::Platform::Array<unsigned char>^ winRtValue = 
            [] (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));
              }
            } (value);

        wrapper->_instance->CurveParameters = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void CurveNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->CurveName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void CurveNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->CurveName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ContainerNamePrefixGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->ContainerNamePrefix;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ContainerNamePrefixSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->ContainerNamePrefix = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ContainerNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->ContainerName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ContainerNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info.This())) {
        return;
      }

      CertificateRequestProperties *wrapper = CertificateRequestProperties::Unwrap<CertificateRequestProperties>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->ContainerName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificateRequestProperties(::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ UnwrapCertificateRequestProperties(Local<Value> value);
  };

  Persistent<FunctionTemplate> CertificateRequestProperties::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificateRequestProperties(::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ 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>(CertificateRequestProperties::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ UnwrapCertificateRequestProperties(Local<Value> value) {
     return CertificateRequestProperties::Unwrap<CertificateRequestProperties>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificateRequestProperties(Local<Object> exports) {
    CertificateRequestProperties::Init(exports);
  }

  class UserCertificateEnrollmentManager : 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>("UserCertificateEnrollmentManager").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);

        Local<Function> func;
        Local<FunctionTemplate> funcTemplate;


          
            Nan::SetPrototypeMethod(localRef, "createRequestAsync", CreateRequestAsync);
            Nan::SetPrototypeMethod(localRef, "installCertificateAsync", InstallCertificateAsync);
            Nan::SetPrototypeMethod(localRef, "importPfxDataAsync", ImportPfxDataAsync);
          



        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("UserCertificateEnrollmentManager").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      UserCertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ 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::Certificates::UserCertificateEnrollmentManager^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^) 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());

      UserCertificateEnrollmentManager *wrapperInstance = new UserCertificateEnrollmentManager(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::Certificates::UserCertificateEnrollmentManager^>(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::Certificates::UserCertificateEnrollmentManager^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapUserCertificateEnrollmentManager(winRtInstance));
    }

    static void CreateRequestAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^>(info.This())) {
        return;
      }

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      UserCertificateEnrollmentManager *wrapper = UserCertificateEnrollmentManager::Unwrap<UserCertificateEnrollmentManager>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Platform::String^>^ op;


      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ arg0 = UnwrapCertificateRequestProperties(info[0]);
          
          op = wrapper->_instance->CreateRequestAsync(arg0);
        }
        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<::Platform::String^> 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::NewString(result->Data());
              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 InstallCertificateAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^>(info.This())) {
        return;
      }

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      UserCertificateEnrollmentManager *wrapper = UserCertificateEnrollmentManager::Unwrap<UserCertificateEnrollmentManager>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;


      if (info.Length() == 3
        && info[0]->IsString()
        && info[1]->IsInt32())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          ::Windows::Security::Cryptography::Certificates::InstallOptions arg1 = static_cast<::Windows::Security::Cryptography::Certificates::InstallOptions>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          
          op = wrapper->_instance->InstallCertificateAsync(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<void> t) {
        try {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};


            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 ImportPfxDataAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^>(info.This())) {
        return;
      }

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      UserCertificateEnrollmentManager *wrapper = UserCertificateEnrollmentManager::Unwrap<UserCertificateEnrollmentManager>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;


      if (info.Length() == 7
        && info[0]->IsString()
        && info[1]->IsString()
        && info[2]->IsInt32()
        && info[3]->IsInt32()
        && info[4]->IsInt32()
        && info[5]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Certificates::ExportOption arg2 = static_cast<::Windows::Security::Cryptography::Certificates::ExportOption>(Nan::To<int32_t>(info[2]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel arg3 = static_cast<::Windows::Security::Cryptography::Certificates::KeyProtectionLevel>(Nan::To<int32_t>(info[3]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::InstallOptions arg4 = static_cast<::Windows::Security::Cryptography::Certificates::InstallOptions>(Nan::To<int32_t>(info[4]).FromMaybe(0));
          Platform::String^ arg5 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[5])));
          
          op = wrapper->_instance->ImportPfxDataAsync(arg0,arg1,arg2,arg3,arg4,arg5);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 8
        && info[0]->IsString()
        && info[1]->IsString()
        && info[2]->IsInt32()
        && info[3]->IsInt32()
        && info[4]->IsInt32()
        && info[5]->IsString()
        && info[6]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Certificates::ExportOption arg2 = static_cast<::Windows::Security::Cryptography::Certificates::ExportOption>(Nan::To<int32_t>(info[2]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel arg3 = static_cast<::Windows::Security::Cryptography::Certificates::KeyProtectionLevel>(Nan::To<int32_t>(info[3]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::InstallOptions arg4 = static_cast<::Windows::Security::Cryptography::Certificates::InstallOptions>(Nan::To<int32_t>(info[4]).FromMaybe(0));
          Platform::String^ arg5 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[5])));
          Platform::String^ arg6 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[6])));
          
          op = wrapper->_instance->ImportPfxDataAsync(arg0,arg1,arg2,arg3,arg4,arg5,arg6);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 4
        && info[0]->IsString()
        && info[1]->IsString()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info[2]))
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Certificates::PfxImportParameters^ arg2 = UnwrapPfxImportParameters(info[2]);
          
          op = wrapper->_instance->ImportPfxDataAsync(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<void> t) {
        try {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};


            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);
          });
        }
      });
    }






    private:
      ::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapUserCertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ UnwrapUserCertificateEnrollmentManager(Local<Value> value);
  };

  Persistent<FunctionTemplate> UserCertificateEnrollmentManager::s_constructorTemplate;

  v8::Local<v8::Value> WrapUserCertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ 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>(UserCertificateEnrollmentManager::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ UnwrapUserCertificateEnrollmentManager(Local<Value> value) {
     return UserCertificateEnrollmentManager::Unwrap<UserCertificateEnrollmentManager>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitUserCertificateEnrollmentManager(Local<Object> exports) {
    UserCertificateEnrollmentManager::Init(exports);
  }

  class PfxImportParameters : 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>("PfxImportParameters").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("readerName").ToLocalChecked(), ReaderNameGetter, ReaderNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyStorageProviderName").ToLocalChecked(), KeyStorageProviderNameGetter, KeyStorageProviderNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyProtectionLevel").ToLocalChecked(), KeyProtectionLevelGetter, KeyProtectionLevelSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("installOptions").ToLocalChecked(), InstallOptionsGetter, InstallOptionsSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("friendlyName").ToLocalChecked(), FriendlyNameGetter, FriendlyNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("exportable").ToLocalChecked(), ExportableGetter, ExportableSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("containerNamePrefix").ToLocalChecked(), ContainerNamePrefixGetter, ContainerNamePrefixSetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("PfxImportParameters").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      PfxImportParameters(::Windows::Security::Cryptography::Certificates::PfxImportParameters^ 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::Certificates::PfxImportParameters^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::PfxImportParameters^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::PfxImportParameters();
        } 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());

      PfxImportParameters *wrapperInstance = new PfxImportParameters(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::Certificates::PfxImportParameters^>(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::Certificates::PfxImportParameters^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::PfxImportParameters^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapPfxImportParameters(winRtInstance));
    }





    static void ReaderNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->ReaderName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ReaderNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->ReaderName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyStorageProviderNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->KeyStorageProviderName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyStorageProviderNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->KeyStorageProviderName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyProtectionLevelGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel result = wrapper->_instance->KeyProtectionLevel;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyProtectionLevelSetter(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::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel winRtValue = static_cast<::Windows::Security::Cryptography::Certificates::KeyProtectionLevel>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->KeyProtectionLevel = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void InstallOptionsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::InstallOptions result = wrapper->_instance->InstallOptions;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void InstallOptionsSetter(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::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::InstallOptions winRtValue = static_cast<::Windows::Security::Cryptography::Certificates::InstallOptions>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->InstallOptions = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void FriendlyNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->FriendlyName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void FriendlyNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->FriendlyName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ExportableGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::ExportOption result = wrapper->_instance->Exportable;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ExportableSetter(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::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::ExportOption winRtValue = static_cast<::Windows::Security::Cryptography::Certificates::ExportOption>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Exportable = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ContainerNamePrefixGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->ContainerNamePrefix;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ContainerNamePrefixSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info.This())) {
        return;
      }

      PfxImportParameters *wrapper = PfxImportParameters::Unwrap<PfxImportParameters>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->ContainerNamePrefix = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::PfxImportParameters^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapPfxImportParameters(::Windows::Security::Cryptography::Certificates::PfxImportParameters^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::PfxImportParameters^ UnwrapPfxImportParameters(Local<Value> value);
  };

  Persistent<FunctionTemplate> PfxImportParameters::s_constructorTemplate;

  v8::Local<v8::Value> WrapPfxImportParameters(::Windows::Security::Cryptography::Certificates::PfxImportParameters^ 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>(PfxImportParameters::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::PfxImportParameters^ UnwrapPfxImportParameters(Local<Value> value) {
     return PfxImportParameters::Unwrap<PfxImportParameters>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPfxImportParameters(Local<Object> exports) {
    PfxImportParameters::Init(exports);
  }

  class CertificateEnrollmentManager : 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>("CertificateEnrollmentManager").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);

        func = Nan::GetFunction(Nan::New<FunctionTemplate>(ImportPfxDataAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("importPfxDataAsync").ToLocalChecked(), func);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(CreateRequestAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("createRequestAsync").ToLocalChecked(), func);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(InstallCertificateAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("installCertificateAsync").ToLocalChecked(), func);
        Nan::SetAccessor(constructor, Nan::New<String>("userCertificateEnrollmentManager").ToLocalChecked(), UserCertificateEnrollmentManagerGetter);


        Nan::Set(exports, Nan::New<String>("CertificateEnrollmentManager").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ 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::Certificates::CertificateEnrollmentManager^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^) 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());

      CertificateEnrollmentManager *wrapperInstance = new CertificateEnrollmentManager(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::Certificates::CertificateEnrollmentManager^>(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::Certificates::CertificateEnrollmentManager^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificateEnrollmentManager(winRtInstance));
    }




    static void ImportPfxDataAsync(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::IAsyncAction^ op;


      if (info.Length() == 4
          && info[0]->IsString()
          && info[1]->IsString()
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::PfxImportParameters^>(info[2]))
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Certificates::PfxImportParameters^ arg2 = UnwrapPfxImportParameters(info[2]);
            
          op = ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager::ImportPfxDataAsync(arg0,arg1,arg2);
        } catch (Platform::Exception ^exception) {
            NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
            return;
        }
      }
      else if (info.Length() == 8
          && info[0]->IsString()
          && info[1]->IsString()
          && info[2]->IsInt32()
          && info[3]->IsInt32()
          && info[4]->IsInt32()
          && info[5]->IsString()
          && info[6]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Certificates::ExportOption arg2 = static_cast<::Windows::Security::Cryptography::Certificates::ExportOption>(Nan::To<int32_t>(info[2]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel arg3 = static_cast<::Windows::Security::Cryptography::Certificates::KeyProtectionLevel>(Nan::To<int32_t>(info[3]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::InstallOptions arg4 = static_cast<::Windows::Security::Cryptography::Certificates::InstallOptions>(Nan::To<int32_t>(info[4]).FromMaybe(0));
          Platform::String^ arg5 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[5])));
          Platform::String^ arg6 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[6])));
            
          op = ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager::ImportPfxDataAsync(arg0,arg1,arg2,arg3,arg4,arg5,arg6);
        } catch (Platform::Exception ^exception) {
            NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
            return;
        }
      }
      else if (info.Length() == 7
          && info[0]->IsString()
          && info[1]->IsString()
          && info[2]->IsInt32()
          && info[3]->IsInt32()
          && info[4]->IsInt32()
          && info[5]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Security::Cryptography::Certificates::ExportOption arg2 = static_cast<::Windows::Security::Cryptography::Certificates::ExportOption>(Nan::To<int32_t>(info[2]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::KeyProtectionLevel arg3 = static_cast<::Windows::Security::Cryptography::Certificates::KeyProtectionLevel>(Nan::To<int32_t>(info[3]).FromMaybe(0));
          ::Windows::Security::Cryptography::Certificates::InstallOptions arg4 = static_cast<::Windows::Security::Cryptography::Certificates::InstallOptions>(Nan::To<int32_t>(info[4]).FromMaybe(0));
          Platform::String^ arg5 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[5])));
            
          op = ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager::ImportPfxDataAsync(arg0,arg1,arg2,arg3,arg4,arg5);
        } 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<void> t)
      {
        try {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


                Local<Value> args[] = {Undefined()};


            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 CreateRequestAsync(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<::Platform::String^>^ op;


      if (info.Length() == 2
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::CertificateRequestProperties^ arg0 = UnwrapCertificateRequestProperties(info[0]);
            
          op = ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager::CreateRequestAsync(arg0);
        } 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<::Platform::String^> 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::NewString(result->Data());
              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 InstallCertificateAsync(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::IAsyncAction^ op;


      if (info.Length() == 3
          && info[0]->IsString()
          && info[1]->IsInt32())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          ::Windows::Security::Cryptography::Certificates::InstallOptions arg1 = static_cast<::Windows::Security::Cryptography::Certificates::InstallOptions>(Nan::To<int32_t>(info[1]).FromMaybe(0));
            
          op = ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager::InstallCertificateAsync(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<void> t)
      {
        try {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


                Local<Value> args[] = {Undefined()};


            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 UserCertificateEnrollmentManagerGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        ::Windows::Security::Cryptography::Certificates::UserCertificateEnrollmentManager^ result = ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager::UserCertificateEnrollmentManager;
        info.GetReturnValue().Set(WrapUserCertificateEnrollmentManager(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ UnwrapCertificateEnrollmentManager(Local<Value> value);
  };

  Persistent<FunctionTemplate> CertificateEnrollmentManager::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificateEnrollmentManager(::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ 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>(CertificateEnrollmentManager::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CertificateEnrollmentManager^ UnwrapCertificateEnrollmentManager(Local<Value> value) {
     return CertificateEnrollmentManager::Unwrap<CertificateEnrollmentManager>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificateEnrollmentManager(Local<Object> exports) {
    CertificateEnrollmentManager::Init(exports);
  }

  class KeyAttestationHelper : 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>("KeyAttestationHelper").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, "getTpmAttestationCredentialId", GetTpmAttestationCredentialId);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(DecryptTpmAttestationCredentialAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("decryptTpmAttestationCredentialAsync").ToLocalChecked(), func);


        Nan::Set(exports, Nan::New<String>("KeyAttestationHelper").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      KeyAttestationHelper(::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ 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::Certificates::KeyAttestationHelper^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^) 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());

      KeyAttestationHelper *wrapperInstance = new KeyAttestationHelper(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::Certificates::KeyAttestationHelper^>(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::Certificates::KeyAttestationHelper^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapKeyAttestationHelper(winRtInstance));
    }




    static void DecryptTpmAttestationCredentialAsync(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<::Platform::String^>^ op;


      if (info.Length() == 3
          && info[0]->IsString()
          && info[1]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
            
          op = ::Windows::Security::Cryptography::Certificates::KeyAttestationHelper::DecryptTpmAttestationCredentialAsync(arg0,arg1);
        } catch (Platform::Exception ^exception) {
            NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
            return;
        }
      }
      else if (info.Length() == 2
          && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[0])));
            
          op = ::Windows::Security::Cryptography::Certificates::KeyAttestationHelper::DecryptTpmAttestationCredentialAsync(arg0);
        } 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<::Platform::String^> 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::NewString(result->Data());
              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 GetTpmAttestationCredentialId(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])));
          
          Platform::String^ result;
          result = ::Windows::Security::Cryptography::Certificates::KeyAttestationHelper::GetTpmAttestationCredentialId(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
 else  {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



    private:
      ::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapKeyAttestationHelper(::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ UnwrapKeyAttestationHelper(Local<Value> value);
  };

  Persistent<FunctionTemplate> KeyAttestationHelper::s_constructorTemplate;

  v8::Local<v8::Value> WrapKeyAttestationHelper(::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ 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>(KeyAttestationHelper::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::KeyAttestationHelper^ UnwrapKeyAttestationHelper(Local<Value> value) {
     return KeyAttestationHelper::Unwrap<KeyAttestationHelper>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitKeyAttestationHelper(Local<Object> exports) {
    KeyAttestationHelper::Init(exports);
  }

  class CertificateQuery : 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>("CertificateQuery").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("thumbprint").ToLocalChecked(), ThumbprintGetter, ThumbprintSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("issuerName").ToLocalChecked(), IssuerNameGetter, IssuerNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hardwareOnly").ToLocalChecked(), HardwareOnlyGetter, HardwareOnlySetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("friendlyName").ToLocalChecked(), FriendlyNameGetter, FriendlyNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("enhancedKeyUsages").ToLocalChecked(), EnhancedKeyUsagesGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("storeName").ToLocalChecked(), StoreNameGetter, StoreNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("includeExpiredCertificates").ToLocalChecked(), IncludeExpiredCertificatesGetter, IncludeExpiredCertificatesSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("includeDuplicates").ToLocalChecked(), IncludeDuplicatesGetter, IncludeDuplicatesSetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CertificateQuery").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CertificateQuery(::Windows::Security::Cryptography::Certificates::CertificateQuery^ 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::Certificates::CertificateQuery^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateQuery^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::CertificateQuery();
        } 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());

      CertificateQuery *wrapperInstance = new CertificateQuery(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::Certificates::CertificateQuery^>(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::Certificates::CertificateQuery^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateQuery^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificateQuery(winRtInstance));
    }





    static void ThumbprintGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->Thumbprint;
        info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<unsigned char>::CreateArrayWrapper(result, 
            [](unsigned char val) -> Local<Value> {
              return Nan::New<Integer>(val);
            },
            [](Local<Value> value) -> bool {
              return value->IsInt32();
            },
            [](Local<Value> value) -> unsigned char {
              return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ThumbprintSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!(NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(value) || value->IsArray())) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try {

        ::Platform::Array<unsigned char>^ winRtValue = 
            [] (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));
              }
            } (value);

        wrapper->_instance->Thumbprint = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void IssuerNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->IssuerName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IssuerNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->IssuerName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void HardwareOnlyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        bool result = wrapper->_instance->HardwareOnly;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void HardwareOnlySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->HardwareOnly = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void FriendlyNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->FriendlyName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void FriendlyNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->FriendlyName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void EnhancedKeyUsagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVector<::Platform::String^>^ result = wrapper->_instance->EnhancedKeyUsages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorWrapper<::Platform::String^>::CreateVectorWrapper(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 StoreNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->StoreName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void StoreNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->StoreName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void IncludeExpiredCertificatesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        bool result = wrapper->_instance->IncludeExpiredCertificates;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IncludeExpiredCertificatesSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IncludeExpiredCertificates = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void IncludeDuplicatesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try  {
        bool result = wrapper->_instance->IncludeDuplicates;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IncludeDuplicatesSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info.This())) {
        return;
      }

      CertificateQuery *wrapper = CertificateQuery::Unwrap<CertificateQuery>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IncludeDuplicates = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CertificateQuery^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificateQuery(::Windows::Security::Cryptography::Certificates::CertificateQuery^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CertificateQuery^ UnwrapCertificateQuery(Local<Value> value);
  };

  Persistent<FunctionTemplate> CertificateQuery::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificateQuery(::Windows::Security::Cryptography::Certificates::CertificateQuery^ 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>(CertificateQuery::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CertificateQuery^ UnwrapCertificateQuery(Local<Value> value) {
     return CertificateQuery::Unwrap<CertificateQuery>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificateQuery(Local<Object> exports) {
    CertificateQuery::Init(exports);
  }

  class CertificateStore : 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>("CertificateStore").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "add", Add);
            Nan::SetPrototypeMethod(localRef, "delete", Delete);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("name").ToLocalChecked(), NameGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CertificateStore").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CertificateStore(::Windows::Security::Cryptography::Certificates::CertificateStore^ 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::Certificates::CertificateStore^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateStore^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateStore^) 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());

      CertificateStore *wrapperInstance = new CertificateStore(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::Certificates::CertificateStore^>(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::Certificates::CertificateStore^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateStore^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificateStore(winRtInstance));
    }


    static void Add(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateStore^>(info.This())) {
        return;
      }

      CertificateStore *wrapper = CertificateStore::Unwrap<CertificateStore>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::Certificate^ arg0 = UnwrapCertificate(info[0]);
          
          wrapper->_instance->Add(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 Delete(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateStore^>(info.This())) {
        return;
      }

      CertificateStore *wrapper = CertificateStore::Unwrap<CertificateStore>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::Certificate^ arg0 = UnwrapCertificate(info[0]);
          
          wrapper->_instance->Delete(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 NameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateStore^>(info.This())) {
        return;
      }

      CertificateStore *wrapper = CertificateStore::Unwrap<CertificateStore>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->Name;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CertificateStore^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificateStore(::Windows::Security::Cryptography::Certificates::CertificateStore^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CertificateStore^ UnwrapCertificateStore(Local<Value> value);
  };

  Persistent<FunctionTemplate> CertificateStore::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificateStore(::Windows::Security::Cryptography::Certificates::CertificateStore^ 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>(CertificateStore::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CertificateStore^ UnwrapCertificateStore(Local<Value> value) {
     return CertificateStore::Unwrap<CertificateStore>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificateStore(Local<Object> exports) {
    CertificateStore::Init(exports);
  }

  class UserCertificateStore : 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>("UserCertificateStore").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);

        Local<Function> func;
        Local<FunctionTemplate> funcTemplate;


          
            Nan::SetPrototypeMethod(localRef, "requestAddAsync", RequestAddAsync);
            Nan::SetPrototypeMethod(localRef, "requestDeleteAsync", RequestDeleteAsync);
          


          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("name").ToLocalChecked(), NameGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("UserCertificateStore").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      UserCertificateStore(::Windows::Security::Cryptography::Certificates::UserCertificateStore^ 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::Certificates::UserCertificateStore^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateStore^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::UserCertificateStore^) 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());

      UserCertificateStore *wrapperInstance = new UserCertificateStore(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::Certificates::UserCertificateStore^>(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::Certificates::UserCertificateStore^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::UserCertificateStore^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapUserCertificateStore(winRtInstance));
    }

    static void RequestAddAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateStore^>(info.This())) {
        return;
      }

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      UserCertificateStore *wrapper = UserCertificateStore::Unwrap<UserCertificateStore>(info.This());

      ::Windows::Foundation::IAsyncOperation<bool>^ op;


      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::Certificate^ arg0 = UnwrapCertificate(info[0]);
          
          op = wrapper->_instance->RequestAddAsync(arg0);
        }
        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<bool> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = Nan::New<Boolean>(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 RequestDeleteAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateStore^>(info.This())) {
        return;
      }

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      UserCertificateStore *wrapper = UserCertificateStore::Unwrap<UserCertificateStore>(info.This());

      ::Windows::Foundation::IAsyncOperation<bool>^ op;


      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::Certificate^ arg0 = UnwrapCertificate(info[0]);
          
          op = wrapper->_instance->RequestDeleteAsync(arg0);
        }
        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<bool> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = Nan::New<Boolean>(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 NameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::UserCertificateStore^>(info.This())) {
        return;
      }

      UserCertificateStore *wrapper = UserCertificateStore::Unwrap<UserCertificateStore>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->Name;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::UserCertificateStore^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapUserCertificateStore(::Windows::Security::Cryptography::Certificates::UserCertificateStore^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::UserCertificateStore^ UnwrapUserCertificateStore(Local<Value> value);
  };

  Persistent<FunctionTemplate> UserCertificateStore::s_constructorTemplate;

  v8::Local<v8::Value> WrapUserCertificateStore(::Windows::Security::Cryptography::Certificates::UserCertificateStore^ 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>(UserCertificateStore::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::UserCertificateStore^ UnwrapUserCertificateStore(Local<Value> value) {
     return UserCertificateStore::Unwrap<UserCertificateStore>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitUserCertificateStore(Local<Object> exports) {
    UserCertificateStore::Init(exports);
  }

  class CertificateStores : 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>("CertificateStores").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, "getUserStoreByName", GetUserStoreByName);
        Nan::SetMethod(constructor, "getStoreByName", GetStoreByName);
        func = Nan::GetFunction(Nan::New<FunctionTemplate>(FindAllAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("findAllAsync").ToLocalChecked(), func);
        Nan::SetAccessor(constructor, Nan::New<String>("intermediateCertificationAuthorities").ToLocalChecked(), IntermediateCertificationAuthoritiesGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("trustedRootCertificationAuthorities").ToLocalChecked(), TrustedRootCertificationAuthoritiesGetter);


        Nan::Set(exports, Nan::New<String>("CertificateStores").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CertificateStores(::Windows::Security::Cryptography::Certificates::CertificateStores^ 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::Certificates::CertificateStores^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateStores^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateStores^) 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());

      CertificateStores *wrapperInstance = new CertificateStores(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::Certificates::CertificateStores^>(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::Certificates::CertificateStores^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateStores^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificateStores(winRtInstance));
    }




    static void FindAllAsync(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::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::Certificate^>^>^ op;


      if (info.Length() == 1)
      {
        try
        {
          op = ::Windows::Security::Cryptography::Certificates::CertificateStores::FindAllAsync();
        } catch (Platform::Exception ^exception) {
            NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
            return;
        }
      }
      else if (info.Length() == 2
          && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateQuery^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::CertificateQuery^ arg0 = UnwrapCertificateQuery(info[0]);
            
          op = ::Windows::Security::Cryptography::Certificates::CertificateStores::FindAllAsync(arg0);
        } 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::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::Certificate^>^> t)
      {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Security::Cryptography::Certificates::Certificate^>::CreateVectorViewWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::Certificate^ val) -> Local<Value> {
              return WrapCertificate(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
              return UnwrapCertificate(value);
            }
          );
              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 GetUserStoreByName(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::Certificates::UserCertificateStore^ result;
          result = ::Windows::Security::Cryptography::Certificates::CertificateStores::GetUserStoreByName(arg0);
          info.GetReturnValue().Set(WrapUserCertificateStore(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 GetStoreByName(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::Certificates::CertificateStore^ result;
          result = ::Windows::Security::Cryptography::Certificates::CertificateStores::GetStoreByName(arg0);
          info.GetReturnValue().Set(WrapCertificateStore(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 IntermediateCertificationAuthoritiesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        ::Windows::Security::Cryptography::Certificates::CertificateStore^ result = ::Windows::Security::Cryptography::Certificates::CertificateStores::IntermediateCertificationAuthorities;
        info.GetReturnValue().Set(WrapCertificateStore(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void TrustedRootCertificationAuthoritiesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        ::Windows::Security::Cryptography::Certificates::CertificateStore^ result = ::Windows::Security::Cryptography::Certificates::CertificateStores::TrustedRootCertificationAuthorities;
        info.GetReturnValue().Set(WrapCertificateStore(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Certificates::CertificateStores^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificateStores(::Windows::Security::Cryptography::Certificates::CertificateStores^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CertificateStores^ UnwrapCertificateStores(Local<Value> value);
  };

  Persistent<FunctionTemplate> CertificateStores::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificateStores(::Windows::Security::Cryptography::Certificates::CertificateStores^ 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>(CertificateStores::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CertificateStores^ UnwrapCertificateStores(Local<Value> value) {
     return CertificateStores::Unwrap<CertificateStores>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificateStores(Local<Object> exports) {
    CertificateStores::Init(exports);
  }

  class StandardCertificateStoreNames : 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>("StandardCertificateStoreNames").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>("intermediateCertificationAuthorities").ToLocalChecked(), IntermediateCertificationAuthoritiesGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("personal").ToLocalChecked(), PersonalGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("trustedRootCertificationAuthorities").ToLocalChecked(), TrustedRootCertificationAuthoritiesGetter);


        Nan::Set(exports, Nan::New<String>("StandardCertificateStoreNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      StandardCertificateStoreNames(::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ 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::Certificates::StandardCertificateStoreNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^) 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());

      StandardCertificateStoreNames *wrapperInstance = new StandardCertificateStoreNames(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::Certificates::StandardCertificateStoreNames^>(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::Certificates::StandardCertificateStoreNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapStandardCertificateStoreNames(winRtInstance));
    }







    static void IntermediateCertificationAuthoritiesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames::IntermediateCertificationAuthorities;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void PersonalGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames::Personal;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void TrustedRootCertificationAuthoritiesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames::TrustedRootCertificationAuthorities;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapStandardCertificateStoreNames(::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ UnwrapStandardCertificateStoreNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> StandardCertificateStoreNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapStandardCertificateStoreNames(::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ 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>(StandardCertificateStoreNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::StandardCertificateStoreNames^ UnwrapStandardCertificateStoreNames(Local<Value> value) {
     return StandardCertificateStoreNames::Unwrap<StandardCertificateStoreNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitStandardCertificateStoreNames(Local<Object> exports) {
    StandardCertificateStoreNames::Init(exports);
  }

  class KeyAlgorithmNames : 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>("KeyAlgorithmNames").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>("dsa").ToLocalChecked(), DsaGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdh256").ToLocalChecked(), Ecdh256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdh384").ToLocalChecked(), Ecdh384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdh521").ToLocalChecked(), Ecdh521Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsa256").ToLocalChecked(), Ecdsa256Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsa384").ToLocalChecked(), Ecdsa384Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsa521").ToLocalChecked(), Ecdsa521Getter);
        Nan::SetAccessor(constructor, Nan::New<String>("rsa").ToLocalChecked(), RsaGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdh").ToLocalChecked(), EcdhGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("ecdsa").ToLocalChecked(), EcdsaGetter);


        Nan::Set(exports, Nan::New<String>("KeyAlgorithmNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      KeyAlgorithmNames(::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ 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::Certificates::KeyAlgorithmNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^) 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());

      KeyAlgorithmNames *wrapperInstance = new KeyAlgorithmNames(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::Certificates::KeyAlgorithmNames^>(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::Certificates::KeyAlgorithmNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapKeyAlgorithmNames(winRtInstance));
    }







    static void DsaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Dsa;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Ecdh256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdh256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Ecdh384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdh384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Ecdh521Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdh521;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Ecdsa256Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdsa256;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Ecdsa384Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdsa384;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void Ecdsa521Getter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdsa521;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void RsaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Rsa;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void EcdhGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdh;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void EcdsaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames::Ecdsa;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapKeyAlgorithmNames(::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ UnwrapKeyAlgorithmNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> KeyAlgorithmNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapKeyAlgorithmNames(::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ 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>(KeyAlgorithmNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::KeyAlgorithmNames^ UnwrapKeyAlgorithmNames(Local<Value> value) {
     return KeyAlgorithmNames::Unwrap<KeyAlgorithmNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitKeyAlgorithmNames(Local<Object> exports) {
    KeyAlgorithmNames::Init(exports);
  }

  class KeyStorageProviderNames : 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>("KeyStorageProviderNames").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>("platformKeyStorageProvider").ToLocalChecked(), PlatformKeyStorageProviderGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("smartcardKeyStorageProvider").ToLocalChecked(), SmartcardKeyStorageProviderGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("softwareKeyStorageProvider").ToLocalChecked(), SoftwareKeyStorageProviderGetter);
        Nan::SetAccessor(constructor, Nan::New<String>("passportKeyStorageProvider").ToLocalChecked(), PassportKeyStorageProviderGetter);


        Nan::Set(exports, Nan::New<String>("KeyStorageProviderNames").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      KeyStorageProviderNames(::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ 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::Certificates::KeyStorageProviderNames^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^) 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());

      KeyStorageProviderNames *wrapperInstance = new KeyStorageProviderNames(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::Certificates::KeyStorageProviderNames^>(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::Certificates::KeyStorageProviderNames^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapKeyStorageProviderNames(winRtInstance));
    }







    static void PlatformKeyStorageProviderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames::PlatformKeyStorageProvider;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SmartcardKeyStorageProviderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames::SmartcardKeyStorageProvider;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void SoftwareKeyStorageProviderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames::SoftwareKeyStorageProvider;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    static void PassportKeyStorageProviderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      try
      {
        Platform::String^ result = ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames::PassportKeyStorageProvider;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      

    private:
      ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapKeyStorageProviderNames(::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ UnwrapKeyStorageProviderNames(Local<Value> value);
  };

  Persistent<FunctionTemplate> KeyStorageProviderNames::s_constructorTemplate;

  v8::Local<v8::Value> WrapKeyStorageProviderNames(::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ 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>(KeyStorageProviderNames::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::KeyStorageProviderNames^ UnwrapKeyStorageProviderNames(Local<Value> value) {
     return KeyStorageProviderNames::Unwrap<KeyStorageProviderNames>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitKeyStorageProviderNames(Local<Object> exports) {
    KeyStorageProviderNames::Init(exports);
  }

  class ChainBuildingParameters : 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>("ChainBuildingParameters").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("validationTimestamp").ToLocalChecked(), ValidationTimestampGetter, ValidationTimestampSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("revocationCheckEnabled").ToLocalChecked(), RevocationCheckEnabledGetter, RevocationCheckEnabledSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("networkRetrievalEnabled").ToLocalChecked(), NetworkRetrievalEnabledGetter, NetworkRetrievalEnabledSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("currentTimeValidationEnabled").ToLocalChecked(), CurrentTimeValidationEnabledGetter, CurrentTimeValidationEnabledSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("authorityInformationAccessEnabled").ToLocalChecked(), AuthorityInformationAccessEnabledGetter, AuthorityInformationAccessEnabledSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("enhancedKeyUsages").ToLocalChecked(), EnhancedKeyUsagesGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("exclusiveTrustRoots").ToLocalChecked(), ExclusiveTrustRootsGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("ChainBuildingParameters").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      ChainBuildingParameters(::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ 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::Certificates::ChainBuildingParameters^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::ChainBuildingParameters();
        } 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());

      ChainBuildingParameters *wrapperInstance = new ChainBuildingParameters(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::Certificates::ChainBuildingParameters^>(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::Certificates::ChainBuildingParameters^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapChainBuildingParameters(winRtInstance));
    }





    static void ValidationTimestampGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try  {
        ::Windows::Foundation::DateTime result = wrapper->_instance->ValidationTimestamp;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ValidationTimestampSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsDate()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try {

        ::Windows::Foundation::DateTime winRtValue = NodeRT::Utils::DateTimeFromJSDate(value);

        wrapper->_instance->ValidationTimestamp = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void RevocationCheckEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try  {
        bool result = wrapper->_instance->RevocationCheckEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void RevocationCheckEnabledSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->RevocationCheckEnabled = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void NetworkRetrievalEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try  {
        bool result = wrapper->_instance->NetworkRetrievalEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void NetworkRetrievalEnabledSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->NetworkRetrievalEnabled = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void CurrentTimeValidationEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try  {
        bool result = wrapper->_instance->CurrentTimeValidationEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void CurrentTimeValidationEnabledSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->CurrentTimeValidationEnabled = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void AuthorityInformationAccessEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try  {
        bool result = wrapper->_instance->AuthorityInformationAccessEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void AuthorityInformationAccessEnabledSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->AuthorityInformationAccessEnabled = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void EnhancedKeyUsagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVector<::Platform::String^>^ result = wrapper->_instance->EnhancedKeyUsages;
        info.GetReturnValue().Set(NodeRT::Collections::VectorWrapper<::Platform::String^>::CreateVectorWrapper(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 ExclusiveTrustRootsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^>(info.This())) {
        return;
      }

      ChainBuildingParameters *wrapper = ChainBuildingParameters::Unwrap<ChainBuildingParameters>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVector<::Windows::Security::Cryptography::Certificates::Certificate^>^ result = wrapper->_instance->ExclusiveTrustRoots;
        info.GetReturnValue().Set(NodeRT::Collections::VectorWrapper<::Windows::Security::Cryptography::Certificates::Certificate^>::CreateVectorWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::Certificate^ val) -> Local<Value> {
              return WrapCertificate(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
              return UnwrapCertificate(value);
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapChainBuildingParameters(::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ UnwrapChainBuildingParameters(Local<Value> value);
  };

  Persistent<FunctionTemplate> ChainBuildingParameters::s_constructorTemplate;

  v8::Local<v8::Value> WrapChainBuildingParameters(::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ 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>(ChainBuildingParameters::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::ChainBuildingParameters^ UnwrapChainBuildingParameters(Local<Value> value) {
     return ChainBuildingParameters::Unwrap<ChainBuildingParameters>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitChainBuildingParameters(Local<Object> exports) {
    ChainBuildingParameters::Init(exports);
  }

  class ChainValidationParameters : 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>("ChainValidationParameters").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("serverDnsName").ToLocalChecked(), ServerDnsNameGetter, ServerDnsNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("certificateChainPolicy").ToLocalChecked(), CertificateChainPolicyGetter, CertificateChainPolicySetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("ChainValidationParameters").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      ChainValidationParameters(::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ 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::Certificates::ChainValidationParameters^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainValidationParameters^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::ChainValidationParameters^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::ChainValidationParameters();
        } 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());

      ChainValidationParameters *wrapperInstance = new ChainValidationParameters(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::Certificates::ChainValidationParameters^>(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::Certificates::ChainValidationParameters^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::ChainValidationParameters^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapChainValidationParameters(winRtInstance));
    }





    static void ServerDnsNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainValidationParameters^>(info.This())) {
        return;
      }

      ChainValidationParameters *wrapper = ChainValidationParameters::Unwrap<ChainValidationParameters>(info.This());

      try  {
        ::Windows::Networking::HostName^ result = wrapper->_instance->ServerDnsName;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Networking", "HostName", result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ServerDnsNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Networking::HostName^>(value)) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainValidationParameters^>(info.This())) {
        return;
      }

      ChainValidationParameters *wrapper = ChainValidationParameters::Unwrap<ChainValidationParameters>(info.This());

      try {

        ::Windows::Networking::HostName^ winRtValue = dynamic_cast<::Windows::Networking::HostName^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->ServerDnsName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void CertificateChainPolicyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainValidationParameters^>(info.This())) {
        return;
      }

      ChainValidationParameters *wrapper = ChainValidationParameters::Unwrap<ChainValidationParameters>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::CertificateChainPolicy result = wrapper->_instance->CertificateChainPolicy;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void CertificateChainPolicySetter(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::Certificates::ChainValidationParameters^>(info.This())) {
        return;
      }

      ChainValidationParameters *wrapper = ChainValidationParameters::Unwrap<ChainValidationParameters>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::CertificateChainPolicy winRtValue = static_cast<::Windows::Security::Cryptography::Certificates::CertificateChainPolicy>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->CertificateChainPolicy = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapChainValidationParameters(::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ UnwrapChainValidationParameters(Local<Value> value);
  };

  Persistent<FunctionTemplate> ChainValidationParameters::s_constructorTemplate;

  v8::Local<v8::Value> WrapChainValidationParameters(::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ 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>(ChainValidationParameters::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ UnwrapChainValidationParameters(Local<Value> value) {
     return ChainValidationParameters::Unwrap<ChainValidationParameters>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitChainValidationParameters(Local<Object> exports) {
    ChainValidationParameters::Init(exports);
  }

  class CertificateChain : 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>("CertificateChain").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "validate", Validate);
            Nan::SetPrototypeMethod(localRef, "getCertificates", GetCertificates);
          




        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CertificateChain").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CertificateChain(::Windows::Security::Cryptography::Certificates::CertificateChain^ 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::Certificates::CertificateChain^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateChain^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateChain^) 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());

      CertificateChain *wrapperInstance = new CertificateChain(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::Certificates::CertificateChain^>(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::Certificates::CertificateChain^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateChain^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificateChain(winRtInstance));
    }


    static void Validate(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateChain^>(info.This())) {
        return;
      }

      CertificateChain *wrapper = CertificateChain::Unwrap<CertificateChain>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::ChainValidationResult result;
          result = wrapper->_instance->Validate();
          info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
          return;
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::ChainValidationParameters^>(info[0]))
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::ChainValidationParameters^ arg0 = UnwrapChainValidationParameters(info[0]);
          
          ::Windows::Security::Cryptography::Certificates::ChainValidationResult result;
          result = wrapper->_instance->Validate(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(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 GetCertificates(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateChain^>(info.This())) {
        return;
      }

      CertificateChain *wrapper = CertificateChain::Unwrap<CertificateChain>(info.This());

      if (info.Length() == 1
        && info[0]->IsBoolean())
      {
        try
        {
          bool arg0 = Nan::To<bool>(info[0]).FromMaybe(false);
          
          ::Windows::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::Certificate^>^ result;
          result = wrapper->_instance->GetCertificates(arg0);
          info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Security::Cryptography::Certificates::Certificate^>::CreateVectorViewWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::Certificate^ val) -> Local<Value> {
              return WrapCertificate(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
              return UnwrapCertificate(value);
            }
          ));
          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::Certificates::CertificateChain^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificateChain(::Windows::Security::Cryptography::Certificates::CertificateChain^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CertificateChain^ UnwrapCertificateChain(Local<Value> value);
  };

  Persistent<FunctionTemplate> CertificateChain::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificateChain(::Windows::Security::Cryptography::Certificates::CertificateChain^ 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>(CertificateChain::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CertificateChain^ UnwrapCertificateChain(Local<Value> value) {
     return CertificateChain::Unwrap<CertificateChain>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificateChain(Local<Object> exports) {
    CertificateChain::Init(exports);
  }

  class CertificateKeyUsages : 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>("CertificateKeyUsages").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("nonRepudiation").ToLocalChecked(), NonRepudiationGetter, NonRepudiationSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyEncipherment").ToLocalChecked(), KeyEnciphermentGetter, KeyEnciphermentSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyCertificateSign").ToLocalChecked(), KeyCertificateSignGetter, KeyCertificateSignSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyAgreement").ToLocalChecked(), KeyAgreementGetter, KeyAgreementSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("encipherOnly").ToLocalChecked(), EncipherOnlyGetter, EncipherOnlySetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("digitalSignature").ToLocalChecked(), DigitalSignatureGetter, DigitalSignatureSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("dataEncipherment").ToLocalChecked(), DataEnciphermentGetter, DataEnciphermentSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("crlSign").ToLocalChecked(), CrlSignGetter, CrlSignSetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CertificateKeyUsages").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CertificateKeyUsages(::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ 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::Certificates::CertificateKeyUsages^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::CertificateKeyUsages();
        } 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());

      CertificateKeyUsages *wrapperInstance = new CertificateKeyUsages(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::Certificates::CertificateKeyUsages^>(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::Certificates::CertificateKeyUsages^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCertificateKeyUsages(winRtInstance));
    }





    static void NonRepudiationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->NonRepudiation;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void NonRepudiationSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->NonRepudiation = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyEnciphermentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->KeyEncipherment;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyEnciphermentSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->KeyEncipherment = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyCertificateSignGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->KeyCertificateSign;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyCertificateSignSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->KeyCertificateSign = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void KeyAgreementGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->KeyAgreement;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void KeyAgreementSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->KeyAgreement = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void EncipherOnlyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->EncipherOnly;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void EncipherOnlySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->EncipherOnly = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void DigitalSignatureGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->DigitalSignature;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void DigitalSignatureSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->DigitalSignature = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void DataEnciphermentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->DataEncipherment;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void DataEnciphermentSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->DataEncipherment = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void CrlSignGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try  {
        bool result = wrapper->_instance->CrlSign;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void CrlSignSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsBoolean()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^>(info.This())) {
        return;
      }

      CertificateKeyUsages *wrapper = CertificateKeyUsages::Unwrap<CertificateKeyUsages>(info.This());

      try {

        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->CrlSign = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCertificateKeyUsages(::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ UnwrapCertificateKeyUsages(Local<Value> value);
  };

  Persistent<FunctionTemplate> CertificateKeyUsages::s_constructorTemplate;

  v8::Local<v8::Value> WrapCertificateKeyUsages(::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ 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>(CertificateKeyUsages::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CertificateKeyUsages^ UnwrapCertificateKeyUsages(Local<Value> value) {
     return CertificateKeyUsages::Unwrap<CertificateKeyUsages>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCertificateKeyUsages(Local<Object> exports) {
    CertificateKeyUsages::Init(exports);
  }

  class SubjectAlternativeNameInfo : 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>("SubjectAlternativeNameInfo").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("distinguishedName").ToLocalChecked(), DistinguishedNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("dnsName").ToLocalChecked(), DnsNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("emailName").ToLocalChecked(), EmailNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("iPAddress").ToLocalChecked(), IPAddressGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("principalName").ToLocalChecked(), PrincipalNameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("url").ToLocalChecked(), UrlGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("SubjectAlternativeNameInfo").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      SubjectAlternativeNameInfo(::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ 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::Certificates::SubjectAlternativeNameInfo^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo();
        } 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());

      SubjectAlternativeNameInfo *wrapperInstance = new SubjectAlternativeNameInfo(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::Certificates::SubjectAlternativeNameInfo^>(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::Certificates::SubjectAlternativeNameInfo^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapSubjectAlternativeNameInfo(winRtInstance));
    }





    static void DistinguishedNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^>(info.This())) {
        return;
      }

      SubjectAlternativeNameInfo *wrapper = SubjectAlternativeNameInfo::Unwrap<SubjectAlternativeNameInfo>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->DistinguishedName;
        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 DnsNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^>(info.This())) {
        return;
      }

      SubjectAlternativeNameInfo *wrapper = SubjectAlternativeNameInfo::Unwrap<SubjectAlternativeNameInfo>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->DnsName;
        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 EmailNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^>(info.This())) {
        return;
      }

      SubjectAlternativeNameInfo *wrapper = SubjectAlternativeNameInfo::Unwrap<SubjectAlternativeNameInfo>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->EmailName;
        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 IPAddressGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^>(info.This())) {
        return;
      }

      SubjectAlternativeNameInfo *wrapper = SubjectAlternativeNameInfo::Unwrap<SubjectAlternativeNameInfo>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->IPAddress;
        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 PrincipalNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^>(info.This())) {
        return;
      }

      SubjectAlternativeNameInfo *wrapper = SubjectAlternativeNameInfo::Unwrap<SubjectAlternativeNameInfo>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->PrincipalName;
        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 UrlGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^>(info.This())) {
        return;
      }

      SubjectAlternativeNameInfo *wrapper = SubjectAlternativeNameInfo::Unwrap<SubjectAlternativeNameInfo>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Platform::String^>^ result = wrapper->_instance->Url;
        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;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapSubjectAlternativeNameInfo(::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ UnwrapSubjectAlternativeNameInfo(Local<Value> value);
  };

  Persistent<FunctionTemplate> SubjectAlternativeNameInfo::s_constructorTemplate;

  v8::Local<v8::Value> WrapSubjectAlternativeNameInfo(::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ 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>(SubjectAlternativeNameInfo::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ UnwrapSubjectAlternativeNameInfo(Local<Value> value) {
     return SubjectAlternativeNameInfo::Unwrap<SubjectAlternativeNameInfo>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitSubjectAlternativeNameInfo(Local<Object> exports) {
    SubjectAlternativeNameInfo::Init(exports);
  }

  class CmsTimestampInfo : 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>("CmsTimestampInfo").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("certificates").ToLocalChecked(), CertificatesGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("signingCertificate").ToLocalChecked(), SigningCertificateGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("timestamp").ToLocalChecked(), TimestampGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CmsTimestampInfo").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CmsTimestampInfo(::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ 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::Certificates::CmsTimestampInfo^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^) 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());

      CmsTimestampInfo *wrapperInstance = new CmsTimestampInfo(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::Certificates::CmsTimestampInfo^>(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::Certificates::CmsTimestampInfo^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCmsTimestampInfo(winRtInstance));
    }





    static void CertificatesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^>(info.This())) {
        return;
      }

      CmsTimestampInfo *wrapper = CmsTimestampInfo::Unwrap<CmsTimestampInfo>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::Certificate^>^ result = wrapper->_instance->Certificates;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Security::Cryptography::Certificates::Certificate^>::CreateVectorViewWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::Certificate^ val) -> Local<Value> {
              return WrapCertificate(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
              return UnwrapCertificate(value);
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SigningCertificateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^>(info.This())) {
        return;
      }

      CmsTimestampInfo *wrapper = CmsTimestampInfo::Unwrap<CmsTimestampInfo>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::Certificate^ result = wrapper->_instance->SigningCertificate;
        info.GetReturnValue().Set(WrapCertificate(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void TimestampGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^>(info.This())) {
        return;
      }

      CmsTimestampInfo *wrapper = CmsTimestampInfo::Unwrap<CmsTimestampInfo>(info.This());

      try  {
        ::Windows::Foundation::DateTime result = wrapper->_instance->Timestamp;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCmsTimestampInfo(::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ UnwrapCmsTimestampInfo(Local<Value> value);
  };

  Persistent<FunctionTemplate> CmsTimestampInfo::s_constructorTemplate;

  v8::Local<v8::Value> WrapCmsTimestampInfo(::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ 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>(CmsTimestampInfo::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ UnwrapCmsTimestampInfo(Local<Value> value) {
     return CmsTimestampInfo::Unwrap<CmsTimestampInfo>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCmsTimestampInfo(Local<Object> exports) {
    CmsTimestampInfo::Init(exports);
  }

  class CmsSignerInfo : 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>("CmsSignerInfo").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);





          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hashAlgorithmName").ToLocalChecked(), HashAlgorithmNameGetter, HashAlgorithmNameSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("certificate").ToLocalChecked(), CertificateGetter, CertificateSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("timestampInfo").ToLocalChecked(), TimestampInfoGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("CmsSignerInfo").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CmsSignerInfo(::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ 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::Certificates::CmsSignerInfo^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsSignerInfo^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try {
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::CmsSignerInfo();
        } 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());

      CmsSignerInfo *wrapperInstance = new CmsSignerInfo(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::Certificates::CmsSignerInfo^>(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::Certificates::CmsSignerInfo^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsSignerInfo^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCmsSignerInfo(winRtInstance));
    }





    static void HashAlgorithmNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(info.This())) {
        return;
      }

      CmsSignerInfo *wrapper = CmsSignerInfo::Unwrap<CmsSignerInfo>(info.This());

      try  {
        Platform::String^ result = wrapper->_instance->HashAlgorithmName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void HashAlgorithmNameSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!value->IsString()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(info.This())) {
        return;
      }

      CmsSignerInfo *wrapper = CmsSignerInfo::Unwrap<CmsSignerInfo>(info.This());

      try {

        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->HashAlgorithmName = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void CertificateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(info.This())) {
        return;
      }

      CmsSignerInfo *wrapper = CmsSignerInfo::Unwrap<CmsSignerInfo>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::Certificate^ result = wrapper->_instance->Certificate;
        info.GetReturnValue().Set(WrapCertificate(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void CertificateSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value)) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(info.This())) {
        return;
      }

      CmsSignerInfo *wrapper = CmsSignerInfo::Unwrap<CmsSignerInfo>(info.This());

      try {

        ::Windows::Security::Cryptography::Certificates::Certificate^ winRtValue = dynamic_cast<::Windows::Security::Cryptography::Certificates::Certificate^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Certificate = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void TimestampInfoGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(info.This())) {
        return;
      }

      CmsSignerInfo *wrapper = CmsSignerInfo::Unwrap<CmsSignerInfo>(info.This());

      try  {
        ::Windows::Security::Cryptography::Certificates::CmsTimestampInfo^ result = wrapper->_instance->TimestampInfo;
        info.GetReturnValue().Set(WrapCmsTimestampInfo(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCmsSignerInfo(::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ UnwrapCmsSignerInfo(Local<Value> value);
  };

  Persistent<FunctionTemplate> CmsSignerInfo::s_constructorTemplate;

  v8::Local<v8::Value> WrapCmsSignerInfo(::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ 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>(CmsSignerInfo::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ UnwrapCmsSignerInfo(Local<Value> value) {
     return CmsSignerInfo::Unwrap<CmsSignerInfo>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCmsSignerInfo(Local<Object> exports) {
    CmsSignerInfo::Init(exports);
  }

  class CmsAttachedSignature : 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>("CmsAttachedSignature").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);

        Local<Function> func;
        Local<FunctionTemplate> funcTemplate;

          
            Nan::SetPrototypeMethod(localRef, "verifySignature", VerifySignature);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("certificates").ToLocalChecked(), CertificatesGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("content").ToLocalChecked(), ContentGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("signers").ToLocalChecked(), SignersGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        func = Nan::GetFunction(Nan::New<FunctionTemplate>(GenerateSignatureAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("generateSignatureAsync").ToLocalChecked(), func);


        Nan::Set(exports, Nan::New<String>("CmsAttachedSignature").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CmsAttachedSignature(::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ 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::Certificates::CmsAttachedSignature^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 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]));
          
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::CmsAttachedSignature(arg0);
        } 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());

      CmsAttachedSignature *wrapperInstance = new CmsAttachedSignature(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::Certificates::CmsAttachedSignature^>(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::Certificates::CmsAttachedSignature^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCmsAttachedSignature(winRtInstance));
    }


    static void VerifySignature(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^>(info.This())) {
        return;
      }

      CmsAttachedSignature *wrapper = CmsAttachedSignature::Unwrap<CmsAttachedSignature>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Security::Cryptography::Certificates::SignatureValidationResult result;
          result = wrapper->_instance->VerifySignature();
          info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(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 GenerateSignatureAsync(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::Storage::Streams::IBuffer^>(info[0])
          && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^>(info[1]) || info[1]->IsArray())
          && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(info[2]) || info[2]->IsArray()))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ {
                   return UnwrapCmsSignerInfo(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Security::Cryptography::Certificates::Certificate^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
                   return UnwrapCertificate(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
            
          op = ::Windows::Security::Cryptography::Certificates::CmsAttachedSignature::GenerateSignatureAsync(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 CertificatesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^>(info.This())) {
        return;
      }

      CmsAttachedSignature *wrapper = CmsAttachedSignature::Unwrap<CmsAttachedSignature>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::Certificate^>^ result = wrapper->_instance->Certificates;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Security::Cryptography::Certificates::Certificate^>::CreateVectorViewWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::Certificate^ val) -> Local<Value> {
              return WrapCertificate(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
              return UnwrapCertificate(value);
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ContentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^>(info.This())) {
        return;
      }

      CmsAttachedSignature *wrapper = CmsAttachedSignature::Unwrap<CmsAttachedSignature>(info.This());

      try  {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->Content;
        info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<unsigned char>::CreateArrayWrapper(result, 
            [](unsigned char val) -> Local<Value> {
              return Nan::New<Integer>(val);
            },
            [](Local<Value> value) -> bool {
              return value->IsInt32();
            },
            [](Local<Value> value) -> unsigned char {
              return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SignersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^>(info.This())) {
        return;
      }

      CmsAttachedSignature *wrapper = CmsAttachedSignature::Unwrap<CmsAttachedSignature>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^ result = wrapper->_instance->Signers;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>::CreateVectorViewWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ val) -> Local<Value> {
              return WrapCmsSignerInfo(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ {
              return UnwrapCmsSignerInfo(value);
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCmsAttachedSignature(::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ UnwrapCmsAttachedSignature(Local<Value> value);
  };

  Persistent<FunctionTemplate> CmsAttachedSignature::s_constructorTemplate;

  v8::Local<v8::Value> WrapCmsAttachedSignature(::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ 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>(CmsAttachedSignature::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CmsAttachedSignature^ UnwrapCmsAttachedSignature(Local<Value> value) {
     return CmsAttachedSignature::Unwrap<CmsAttachedSignature>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCmsAttachedSignature(Local<Object> exports) {
    CmsAttachedSignature::Init(exports);
  }

  class CmsDetachedSignature : 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>("CmsDetachedSignature").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);

        Local<Function> func;
        Local<FunctionTemplate> funcTemplate;


          
            Nan::SetPrototypeMethod(localRef, "verifySignatureAsync", VerifySignatureAsync);
          


          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("certificates").ToLocalChecked(), CertificatesGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("signers").ToLocalChecked(), SignersGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);

        func = Nan::GetFunction(Nan::New<FunctionTemplate>(GenerateSignatureAsync)).ToLocalChecked();
        Nan::Set(constructor, Nan::New<String>("generateSignatureAsync").ToLocalChecked(), func);


        Nan::Set(exports, Nan::New<String>("CmsDetachedSignature").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      CmsDetachedSignature(::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ 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::Certificates::CmsDetachedSignature^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^>(info[0])) {
        try {
          winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^) NodeRT::Utils::GetObjectInstance(info[0]);
        } catch (Platform::Exception ^exception) {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 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]));
          
          winRtInstance = ref new ::Windows::Security::Cryptography::Certificates::CmsDetachedSignature(arg0);
        } 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());

      CmsDetachedSignature *wrapperInstance = new CmsDetachedSignature(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::Certificates::CmsDetachedSignature^>(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::Certificates::CmsDetachedSignature^ winRtInstance;
      try {
        winRtInstance = (::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapCmsDetachedSignature(winRtInstance));
    }

    static void VerifySignatureAsync(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^>(info.This())) {
        return;
      }

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction()) {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
        return;
      }

      CmsDetachedSignature *wrapper = CmsDetachedSignature::Unwrap<CmsDetachedSignature>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Security::Cryptography::Certificates::SignatureValidationResult>^ op;


      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IInputStream^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IInputStream^ arg0 = dynamic_cast<::Windows::Storage::Streams::IInputStream^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->VerifySignatureAsync(arg0);
        }
        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::Certificates::SignatureValidationResult> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = Nan::New<Integer>(static_cast<int>(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 GenerateSignatureAsync(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::Storage::Streams::IInputStream^>(info[0])
          && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^>(info[1]) || info[1]->IsArray())
          && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(info[2]) || info[2]->IsArray()))
      {
        try
        {
          ::Windows::Storage::Streams::IInputStream^ arg0 = dynamic_cast<::Windows::Storage::Streams::IInputStream^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ {
                   return UnwrapCmsSignerInfo(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Security::Cryptography::Certificates::Certificate^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
                   return UnwrapCertificate(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Security::Cryptography::Certificates::Certificate^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
            
          op = ::Windows::Security::Cryptography::Certificates::CmsDetachedSignature::GenerateSignatureAsync(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 CertificatesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^>(info.This())) {
        return;
      }

      CmsDetachedSignature *wrapper = CmsDetachedSignature::Unwrap<CmsDetachedSignature>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::Certificate^>^ result = wrapper->_instance->Certificates;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Security::Cryptography::Certificates::Certificate^>::CreateVectorViewWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::Certificate^ val) -> Local<Value> {
              return WrapCertificate(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::Certificate^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::Certificate^ {
              return UnwrapCertificate(value);
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SignersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^>(info.This())) {
        return;
      }

      CmsDetachedSignature *wrapper = CmsDetachedSignature::Unwrap<CmsDetachedSignature>(info.This());

      try  {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>^ result = wrapper->_instance->Signers;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>::CreateVectorViewWrapper(result, 
            [](::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ val) -> Local<Value> {
              return WrapCmsSignerInfo(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Security::Cryptography::Certificates::CmsSignerInfo^>(value);
            },
            [](Local<Value> value) -> ::Windows::Security::Cryptography::Certificates::CmsSignerInfo^ {
              return UnwrapCmsSignerInfo(value);
            }
          ));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapCmsDetachedSignature(::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ wintRtInstance);
      friend ::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ UnwrapCmsDetachedSignature(Local<Value> value);
  };

  Persistent<FunctionTemplate> CmsDetachedSignature::s_constructorTemplate;

  v8::Local<v8::Value> WrapCmsDetachedSignature(::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ 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>(CmsDetachedSignature::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Security::Cryptography::Certificates::CmsDetachedSignature^ UnwrapCmsDetachedSignature(Local<Value> value) {
     return CmsDetachedSignature::Unwrap<CmsDetachedSignature>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCmsDetachedSignature(Local<Object> exports) {
    CmsDetachedSignature::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::Certificates::InitEnrollKeyUsagesEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitKeyProtectionLevelEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitExportOptionEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitKeySizeEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitInstallOptionsEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateChainPolicyEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitChainValidationResultEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitSignatureValidationResultEnum(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificate(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateRequestProperties(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitUserCertificateEnrollmentManager(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitPfxImportParameters(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateEnrollmentManager(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitKeyAttestationHelper(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateQuery(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateStore(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitUserCertificateStore(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateStores(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitStandardCertificateStoreNames(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitKeyAlgorithmNames(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitKeyStorageProviderNames(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitChainBuildingParameters(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitChainValidationParameters(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateChain(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCertificateKeyUsages(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitSubjectAlternativeNameInfo(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCmsTimestampInfo(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCmsSignerInfo(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCmsAttachedSignature(target);
      NodeRT::Windows::Security::Cryptography::Certificates::InitCmsDetachedSignature(target);


  NodeRT::Utils::RegisterNameSpace("Windows.Security.Cryptography.Certificates", target);
}



NODE_MODULE(binding, init)
