// Copyright (c) Microsoft Corporation
// All rights reserved. 
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED ON AN  *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//
// See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.

// TODO: Verify that this is is still needed..
#define NTDDI_VERSION 0x06010000

#include <v8.h>
#include "nan.h"
#include <string>
#include <ppltasks.h>
#include "CollectionsConverter.h"
#include "CollectionsWrap.h"
#include "node-async.h"
#include "NodeRtUtils.h"
#include "OpaqueWrapper.h"
#include "WrapperBase.h"

#using <Windows.WinMD>

// this undefs fixes the issues of compiling Windows.Data.Json, Windows.Storag.FileProperties, and Windows.Stroage.Search
// Some of the node header files brings windows definitions with the same names as some of the WinRT methods
#undef DocumentProperties
#undef GetObject
#undef CreateEvent
#undef FindText
#undef SendMessage

const char* REGISTRATION_TOKEN_MAP_PROPERTY_NAME = "__registrationTokenMap__";

using v8::Array;
using v8::String;
using v8::Handle;
using v8::Value;
using v8::Boolean;
using v8::Integer;
using v8::FunctionTemplate;
using v8::Object;
using v8::Local;
using v8::Function;
using v8::Date;
using v8::Number;
using v8::PropertyAttribute;
using v8::Primitive;
using Nan::HandleScope;
using Nan::Persistent;
using Nan::Undefined;
using Nan::True;
using Nan::False;
using Nan::Null;
using Nan::MaybeLocal;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::TryCatch;
using namespace concurrency;

namespace NodeRT { namespace Windows { namespace Media { namespace Protection { namespace PlayReady { 

  v8::Local<v8::Value> WrapPlayReadyContentHeader(::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ UnwrapPlayReadyContentHeader(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadySoapMessage(::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ UnwrapPlayReadySoapMessage(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyContentResolver(::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ UnwrapPlayReadyContentResolver(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyIndividualizationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ UnwrapPlayReadyIndividualizationServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyDomainJoinServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ UnwrapPlayReadyDomainJoinServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyDomainLeaveServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ UnwrapPlayReadyDomainLeaveServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ UnwrapPlayReadyLicenseAcquisitionServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyMeteringReportServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ UnwrapPlayReadyMeteringReportServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyRevocationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ UnwrapPlayReadyRevocationServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyLicenseManagement(::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^ UnwrapPlayReadyLicenseManagement(Local<Value> value);
  
  v8::Local<v8::Value> WrapIPlayReadyLicense(::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ UnwrapIPlayReadyLicense(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyLicense(::Windows::Media::Protection::PlayReady::PlayReadyLicense^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyLicense^ UnwrapPlayReadyLicense(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyLicenseIterable(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^ UnwrapPlayReadyLicenseIterable(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyLicenseIterator(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ UnwrapPlayReadyLicenseIterator(Local<Value> value);
  
  v8::Local<v8::Value> WrapIPlayReadyDomain(::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ UnwrapIPlayReadyDomain(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyDomain(::Windows::Media::Protection::PlayReady::PlayReadyDomain^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyDomain^ UnwrapPlayReadyDomain(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyDomainIterable(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^ UnwrapPlayReadyDomainIterable(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyDomainIterator(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ UnwrapPlayReadyDomainIterator(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyStatics(::Windows::Media::Protection::PlayReady::PlayReadyStatics^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyStatics^ UnwrapPlayReadyStatics(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ UnwrapPlayReadySecureStopServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadySecureStopIterable(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^ UnwrapPlayReadySecureStopIterable(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadySecureStopIterator(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ UnwrapPlayReadySecureStopIterator(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyITADataGenerator(::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ UnwrapPlayReadyITADataGenerator(Local<Value> value);
  
  v8::Local<v8::Value> WrapIPlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ UnwrapIPlayReadyLicenseSession(Local<Value> value);
  
  v8::Local<v8::Value> WrapPlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ UnwrapPlayReadyLicenseSession(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDDownloadEngine(::Windows::Media::Protection::PlayReady::INDDownloadEngine^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDDownloadEngine^ UnwrapINDDownloadEngine(Local<Value> value);
  
  v8::Local<v8::Value> WrapNDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ UnwrapNDDownloadEngineNotifier(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^ UnwrapINDDownloadEngineNotifier(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ UnwrapINDLicenseFetchDescriptor(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDCustomData(::Windows::Media::Protection::PlayReady::INDCustomData^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDCustomData^ UnwrapINDCustomData(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDStreamParser(::Windows::Media::Protection::PlayReady::INDStreamParser^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDStreamParser^ UnwrapINDStreamParser(Local<Value> value);
  
  v8::Local<v8::Value> WrapNDStreamParserNotifier(::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ UnwrapNDStreamParserNotifier(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDStreamParserNotifier(::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^ UnwrapINDStreamParserNotifier(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDSendResult(::Windows::Media::Protection::PlayReady::INDSendResult^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDSendResult^ UnwrapINDSendResult(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDMessenger(::Windows::Media::Protection::PlayReady::INDMessenger^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDMessenger^ UnwrapINDMessenger(Local<Value> value);
  
  v8::Local<v8::Value> WrapNDTCPMessenger(::Windows::Media::Protection::PlayReady::NDTCPMessenger^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::NDTCPMessenger^ UnwrapNDTCPMessenger(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDTransmitterProperties(::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ UnwrapINDTransmitterProperties(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDStartResult(::Windows::Media::Protection::PlayReady::INDStartResult^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDStartResult^ UnwrapINDStartResult(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDLicenseFetchResult(::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ UnwrapINDLicenseFetchResult(Local<Value> value);
  
  v8::Local<v8::Value> WrapNDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ UnwrapNDLicenseFetchDescriptor(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDRegistrationCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ UnwrapINDRegistrationCompletedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapNDCustomData(::Windows::Media::Protection::PlayReady::NDCustomData^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::NDCustomData^ UnwrapNDCustomData(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDProximityDetectionCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ UnwrapINDProximityDetectionCompletedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDLicenseFetchCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ UnwrapINDLicenseFetchCompletedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapNDClient(::Windows::Media::Protection::PlayReady::NDClient^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::NDClient^ UnwrapNDClient(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDClosedCaptionDataReceivedEventArgs(::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ UnwrapINDClosedCaptionDataReceivedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapINDStorageFileHelper(::Windows::Media::Protection::PlayReady::INDStorageFileHelper^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::INDStorageFileHelper^ UnwrapINDStorageFileHelper(Local<Value> value);
  
  v8::Local<v8::Value> WrapNDStorageFileHelper(::Windows::Media::Protection::PlayReady::NDStorageFileHelper^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::NDStorageFileHelper^ UnwrapNDStorageFileHelper(Local<Value> value);
  
  v8::Local<v8::Value> WrapIPlayReadyServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ UnwrapIPlayReadyServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapIPlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ UnwrapIPlayReadyLicenseAcquisitionServiceRequest(Local<Value> value);
  
  v8::Local<v8::Value> WrapIPlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ wintRtInstance);
  ::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ UnwrapIPlayReadySecureStopServiceRequest(Local<Value> value);
  


  static void InitPlayReadyDecryptorSetupEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("PlayReadyDecryptorSetup").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("uninitialized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyDecryptorSetup::Uninitialized)));
	Nan::Set(enumObject, Nan::New<String>("onDemand").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyDecryptorSetup::OnDemand)));
  }


  static void InitPlayReadyEncryptionAlgorithmEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("PlayReadyEncryptionAlgorithm").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("unprotected").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm::Unprotected)));
	Nan::Set(enumObject, Nan::New<String>("aes128Ctr").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm::Aes128Ctr)));
	Nan::Set(enumObject, Nan::New<String>("cocktail").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm::Cocktail)));
	Nan::Set(enumObject, Nan::New<String>("uninitialized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm::Uninitialized)));
  }


  static void InitPlayReadyHardwareDRMFeaturesEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("PlayReadyHardwareDRMFeatures").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("hardwareDRM").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyHardwareDRMFeatures::HardwareDRM)));
	Nan::Set(enumObject, Nan::New<String>("hEVC").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyHardwareDRMFeatures::HEVC)));
  }


  static void InitPlayReadyITADataFormatEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("PlayReadyITADataFormat").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("serializedProperties").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyITADataFormat::SerializedProperties)));
	Nan::Set(enumObject, Nan::New<String>("serializedProperties_WithContentProtectionWrapper").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::PlayReadyITADataFormat::SerializedProperties_WithContentProtectionWrapper)));
  }


  static void InitNDCertificateTypeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDCertificateType").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("unknown").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Unknown)));
	Nan::Set(enumObject, Nan::New<String>("pC").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::PC)));
	Nan::Set(enumObject, Nan::New<String>("device").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Device)));
	Nan::Set(enumObject, Nan::New<String>("domain").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Domain)));
	Nan::Set(enumObject, Nan::New<String>("issuer").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Issuer)));
	Nan::Set(enumObject, Nan::New<String>("crlSigner").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::CrlSigner)));
	Nan::Set(enumObject, Nan::New<String>("service").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Service)));
	Nan::Set(enumObject, Nan::New<String>("silverlight").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Silverlight)));
	Nan::Set(enumObject, Nan::New<String>("application").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Application)));
	Nan::Set(enumObject, Nan::New<String>("metering").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Metering)));
	Nan::Set(enumObject, Nan::New<String>("keyFileSigner").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::KeyFileSigner)));
	Nan::Set(enumObject, Nan::New<String>("server").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::Server)));
	Nan::Set(enumObject, Nan::New<String>("licenseSigner").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateType::LicenseSigner)));
  }


  static void InitNDCertificatePlatformIDEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDCertificatePlatformID").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("windows").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::Windows)));
	Nan::Set(enumObject, Nan::New<String>("oSX").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::OSX)));
	Nan::Set(enumObject, Nan::New<String>("windowsOnARM").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::WindowsOnARM)));
	Nan::Set(enumObject, Nan::New<String>("windowsMobile7").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::WindowsMobile7)));
	Nan::Set(enumObject, Nan::New<String>("iOSOnARM").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::iOSOnARM)));
	Nan::Set(enumObject, Nan::New<String>("xBoxOnPPC").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::XBoxOnPPC)));
	Nan::Set(enumObject, Nan::New<String>("windowsPhone8OnARM").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::WindowsPhone8OnARM)));
	Nan::Set(enumObject, Nan::New<String>("windowsPhone8OnX86").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::WindowsPhone8OnX86)));
	Nan::Set(enumObject, Nan::New<String>("xboxOne").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::XboxOne)));
	Nan::Set(enumObject, Nan::New<String>("androidOnARM").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::AndroidOnARM)));
	Nan::Set(enumObject, Nan::New<String>("windowsPhone81OnARM").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::WindowsPhone81OnARM)));
	Nan::Set(enumObject, Nan::New<String>("windowsPhone81OnX86").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificatePlatformID::WindowsPhone81OnX86)));
  }


  static void InitNDCertificateFeatureEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDCertificateFeature").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("transmitter").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateFeature::Transmitter)));
	Nan::Set(enumObject, Nan::New<String>("receiver").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateFeature::Receiver)));
	Nan::Set(enumObject, Nan::New<String>("sharedCertificate").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateFeature::SharedCertificate)));
	Nan::Set(enumObject, Nan::New<String>("secureClock").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateFeature::SecureClock)));
	Nan::Set(enumObject, Nan::New<String>("antiRollBackClock").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateFeature::AntiRollBackClock)));
	Nan::Set(enumObject, Nan::New<String>("cRLS").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateFeature::CRLS)));
	Nan::Set(enumObject, Nan::New<String>("playReady3Features").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDCertificateFeature::PlayReady3Features)));
  }


  static void InitNDProximityDetectionTypeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDProximityDetectionType").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("uDP").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDProximityDetectionType::UDP)));
	Nan::Set(enumObject, Nan::New<String>("tCP").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDProximityDetectionType::TCP)));
	Nan::Set(enumObject, Nan::New<String>("transportAgnostic").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDProximityDetectionType::TransportAgnostic)));
  }


  static void InitNDMediaStreamTypeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDMediaStreamType").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("audio").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDMediaStreamType::Audio)));
	Nan::Set(enumObject, Nan::New<String>("video").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDMediaStreamType::Video)));
  }


  static void InitNDContentIDTypeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDContentIDType").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("keyID").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDContentIDType::KeyID)));
	Nan::Set(enumObject, Nan::New<String>("playReadyObject").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDContentIDType::PlayReadyObject)));
	Nan::Set(enumObject, Nan::New<String>("custom").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDContentIDType::Custom)));
  }


  static void InitNDClosedCaptionFormatEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDClosedCaptionFormat").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("aTSC").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat::ATSC)));
	Nan::Set(enumObject, Nan::New<String>("sCTE20").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat::SCTE20)));
	Nan::Set(enumObject, Nan::New<String>("unknown").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat::Unknown)));
  }


  static void InitNDStartAsyncOptionsEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("NDStartAsyncOptions").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("mutualAuthentication").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDStartAsyncOptions::MutualAuthentication)));
	Nan::Set(enumObject, Nan::New<String>("waitForLicenseDescriptor").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Protection::PlayReady::NDStartAsyncOptions::WaitForLicenseDescriptor)));
  }



  
  class PlayReadyContentHeader : 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>("PlayReadyContentHeader").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "getSerializedHeader", GetSerializedHeader);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customAttributes").ToLocalChecked(), CustomAttributesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("decryptorSetup").ToLocalChecked(), DecryptorSetupGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainServiceId").ToLocalChecked(), DomainServiceIdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("encryptionType").ToLocalChecked(), EncryptionTypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("headerWithEmbeddedUpdates").ToLocalChecked(), HeaderWithEmbeddedUpdatesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyId").ToLocalChecked(), KeyIdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyIdString").ToLocalChecked(), KeyIdStringGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("licenseAcquisitionUrl").ToLocalChecked(), LicenseAcquisitionUrlGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("licenseAcquisitionUserInterfaceUrl").ToLocalChecked(), LicenseAcquisitionUserInterfaceUrlGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyIdStrings").ToLocalChecked(), KeyIdStringsGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("keyIds").ToLocalChecked(), KeyIdsGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyContentHeader").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyContentHeader(::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ 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::Media::Protection::PlayReady::PlayReadyContentHeader^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 8
        && info[0]->IsUint32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<::Platform::Guid>^>(info[1]) || info[1]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<::Platform::String^>^>(info[2]) || info[2]->IsArray())
        && info[3]->IsInt32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[4])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[5])
        && info[6]->IsString()
        && NodeRT::Utils::IsGuid(info[7]))
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          ::Platform::Array<::Platform::Guid>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<::Platform::Guid>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<::Platform::Guid>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsGuid(value);
                 },
                 [](Local<Value> value) -> ::Platform::Guid {
                   return NodeRT::Utils::GuidFromJs(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<::Platform::Guid>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Platform::Array<::Platform::String^>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<::Platform::String^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Local<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
          ::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm arg3 = static_cast<::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm>(Nan::To<int32_t>(info[3]).FromMaybe(0));
          ::Windows::Foundation::Uri^ arg4 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[4]));
          ::Windows::Foundation::Uri^ arg5 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[5]));
          Platform::String^ arg6 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[6])));
          ::Platform::Guid arg7 = NodeRT::Utils::GuidFromJs(info[7]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader(arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 5
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[2])
        && info[3]->IsString()
        && NodeRT::Utils::IsGuid(info[4]))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Windows::Foundation::Uri^ arg1 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Foundation::Uri^ arg2 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[2]));
          Platform::String^ arg3 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[3])));
          ::Platform::Guid arg4 = NodeRT::Utils::GuidFromJs(info[4]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader(arg0,arg1,arg2,arg3,arg4);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 7
        && NodeRT::Utils::IsGuid(info[0])
        && info[1]->IsString()
        && info[2]->IsInt32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[3])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[4])
        && info[5]->IsString()
        && NodeRT::Utils::IsGuid(info[6]))
      {
        try
        {
          ::Platform::Guid arg0 = NodeRT::Utils::GuidFromJs(info[0]);
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          ::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm arg2 = static_cast<::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm>(Nan::To<int32_t>(info[2]).FromMaybe(0));
          ::Windows::Foundation::Uri^ arg3 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[3]));
          ::Windows::Foundation::Uri^ arg4 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[4]));
          Platform::String^ arg5 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[5])));
          ::Platform::Guid arg6 = NodeRT::Utils::GuidFromJs(info[6]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader(arg0,arg1,arg2,arg3,arg4,arg5,arg6);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader(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());

      PlayReadyContentHeader *wrapperInstance = new PlayReadyContentHeader(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::Media::Protection::PlayReady::PlayReadyContentHeader^>(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::Media::Protection::PlayReady::PlayReadyContentHeader^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyContentHeader(winRtInstance));
    }


  
    static void GetSerializedHeader(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Platform::Array<unsigned char>^ result;
          result = wrapper->_instance->GetSerializedHeader();
          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 CustomAttributesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->CustomAttributes;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DecryptorSetupGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::PlayReadyDecryptorSetup result = wrapper->_instance->DecryptorSetup;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainServiceId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void EncryptionTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::PlayReadyEncryptionAlgorithm result = wrapper->_instance->EncryptionType;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void HeaderWithEmbeddedUpdatesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ result = wrapper->_instance->HeaderWithEmbeddedUpdates;
        info.GetReturnValue().Set(WrapPlayReadyContentHeader(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void KeyIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->KeyId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void KeyIdStringGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->KeyIdString;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LicenseAcquisitionUrlGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->LicenseAcquisitionUrl;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LicenseAcquisitionUserInterfaceUrlGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->LicenseAcquisitionUserInterfaceUrl;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void KeyIdStringsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Platform::Array<::Platform::String^>^ result = wrapper->_instance->KeyIdStrings;
        info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<::Platform::String^>::CreateArrayWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void KeyIdsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info.This()))
      {
        return;
      }

      PlayReadyContentHeader *wrapper = PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(info.This());

      try 
      {
        ::Platform::Array<::Platform::Guid>^ result = wrapper->_instance->KeyIds;
        info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<::Platform::Guid>::CreateArrayWrapper(result, 
            [](::Platform::Guid val) -> Local<Value> {
              return NodeRT::Utils::GuidToJs(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsGuid(value);
            },
            [](Local<Value> value) -> ::Platform::Guid {
              return NodeRT::Utils::GuidFromJs(value);
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyContentHeader(::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ UnwrapPlayReadyContentHeader(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyContentHeader::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyContentHeader(::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ 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>(PlayReadyContentHeader::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ UnwrapPlayReadyContentHeader(Local<Value> value)
  {
     return PlayReadyContentHeader::Unwrap<PlayReadyContentHeader>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyContentHeader(Local<Object> exports)
  {
    PlayReadyContentHeader::Init(exports);
  }

  class PlayReadySoapMessage : 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>("PlayReadySoapMessage").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "getMessageBody", GetMessageBody);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("messageHeaders").ToLocalChecked(), MessageHeadersGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadySoapMessage").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadySoapMessage(::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ 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::Media::Protection::PlayReady::PlayReadySoapMessage^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^) 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());

      PlayReadySoapMessage *wrapperInstance = new PlayReadySoapMessage(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::Media::Protection::PlayReady::PlayReadySoapMessage^>(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::Media::Protection::PlayReady::PlayReadySoapMessage^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadySoapMessage(winRtInstance));
    }


  
    static void GetMessageBody(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^>(info.This()))
      {
        return;
      }

      PlayReadySoapMessage *wrapper = PlayReadySoapMessage::Unwrap<PlayReadySoapMessage>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Platform::Array<unsigned char>^ result;
          result = wrapper->_instance->GetMessageBody();
          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 MessageHeadersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^>(info.This()))
      {
        return;
      }

      PlayReadySoapMessage *wrapper = PlayReadySoapMessage::Unwrap<PlayReadySoapMessage>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IPropertySet^ result = wrapper->_instance->MessageHeaders;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation.Collections", "IPropertySet", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^>(info.This()))
      {
        return;
      }

      PlayReadySoapMessage *wrapper = PlayReadySoapMessage::Unwrap<PlayReadySoapMessage>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadySoapMessage(::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ UnwrapPlayReadySoapMessage(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadySoapMessage::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadySoapMessage(::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ 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>(PlayReadySoapMessage::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ UnwrapPlayReadySoapMessage(Local<Value> value)
  {
     return PlayReadySoapMessage::Unwrap<PlayReadySoapMessage>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadySoapMessage(Local<Object> exports)
  {
    PlayReadySoapMessage::Init(exports);
  }

  class PlayReadyContentResolver : 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>("PlayReadyContentResolver").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "serviceRequest", ServiceRequest);

      Nan::Set(exports, Nan::New<String>("PlayReadyContentResolver").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyContentResolver(::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ 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::Media::Protection::PlayReady::PlayReadyContentResolver^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^) 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());

      PlayReadyContentResolver *wrapperInstance = new PlayReadyContentResolver(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::Media::Protection::PlayReady::PlayReadyContentResolver^>(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::Media::Protection::PlayReady::PlayReadyContentResolver^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyContentResolver(winRtInstance));
    }


  


    static void ServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ arg0 = UnwrapPlayReadyContentHeader(info[0]);
          
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = ::Windows::Media::Protection::PlayReady::PlayReadyContentResolver::ServiceRequest(arg0);
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }



  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyContentResolver(::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ UnwrapPlayReadyContentResolver(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyContentResolver::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyContentResolver(::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ 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>(PlayReadyContentResolver::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyContentResolver^ UnwrapPlayReadyContentResolver(Local<Value> value)
  {
     return PlayReadyContentResolver::Unwrap<PlayReadyContentResolver>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyContentResolver(Local<Object> exports)
  {
    PlayReadyContentResolver::Init(exports);
  }

  class PlayReadyIndividualizationServiceRequest : 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>("PlayReadyIndividualizationServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("protectionSystem").ToLocalChecked(), ProtectionSystemGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("type").ToLocalChecked(), TypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyIndividualizationServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyIndividualizationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ 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::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest();
        }
        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());

      PlayReadyIndividualizationServiceRequest *wrapperInstance = new PlayReadyIndividualizationServiceRequest(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::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(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::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyIndividualizationServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(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;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ProtectionSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ProtectionSystem;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->Type;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyIndividualizationServiceRequest *wrapper = PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyIndividualizationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ UnwrapPlayReadyIndividualizationServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyIndividualizationServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyIndividualizationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ 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>(PlayReadyIndividualizationServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyIndividualizationServiceRequest^ UnwrapPlayReadyIndividualizationServiceRequest(Local<Value> value)
  {
     return PlayReadyIndividualizationServiceRequest::Unwrap<PlayReadyIndividualizationServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyIndividualizationServiceRequest(Local<Object> exports)
  {
    PlayReadyIndividualizationServiceRequest::Init(exports);
  }

  class PlayReadyDomainJoinServiceRequest : 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>("PlayReadyDomainJoinServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("protectionSystem").ToLocalChecked(), ProtectionSystemGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("type").ToLocalChecked(), TypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainServiceId").ToLocalChecked(), DomainServiceIdGetter, DomainServiceIdSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainFriendlyName").ToLocalChecked(), DomainFriendlyNameGetter, DomainFriendlyNameSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainAccountId").ToLocalChecked(), DomainAccountIdGetter, DomainAccountIdSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyDomainJoinServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyDomainJoinServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ 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::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest();
        }
        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());

      PlayReadyDomainJoinServiceRequest *wrapperInstance = new PlayReadyDomainJoinServiceRequest(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::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(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::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyDomainJoinServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(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;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ProtectionSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ProtectionSystem;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->Type;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainServiceId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsGuid(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        
        ::Platform::Guid winRtValue = NodeRT::Utils::GuidFromJs(value);

        wrapper->_instance->DomainServiceId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DomainFriendlyNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->DomainFriendlyName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainFriendlyNameSetter(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::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->DomainFriendlyName = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DomainAccountIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainAccountId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainAccountIdSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsGuid(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        
        ::Platform::Guid winRtValue = NodeRT::Utils::GuidFromJs(value);

        wrapper->_instance->DomainAccountId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainJoinServiceRequest *wrapper = PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyDomainJoinServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ UnwrapPlayReadyDomainJoinServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyDomainJoinServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyDomainJoinServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ 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>(PlayReadyDomainJoinServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyDomainJoinServiceRequest^ UnwrapPlayReadyDomainJoinServiceRequest(Local<Value> value)
  {
     return PlayReadyDomainJoinServiceRequest::Unwrap<PlayReadyDomainJoinServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyDomainJoinServiceRequest(Local<Object> exports)
  {
    PlayReadyDomainJoinServiceRequest::Init(exports);
  }

  class PlayReadyDomainLeaveServiceRequest : 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>("PlayReadyDomainLeaveServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("protectionSystem").ToLocalChecked(), ProtectionSystemGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("type").ToLocalChecked(), TypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainServiceId").ToLocalChecked(), DomainServiceIdGetter, DomainServiceIdSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainAccountId").ToLocalChecked(), DomainAccountIdGetter, DomainAccountIdSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyDomainLeaveServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyDomainLeaveServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ 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::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest();
        }
        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());

      PlayReadyDomainLeaveServiceRequest *wrapperInstance = new PlayReadyDomainLeaveServiceRequest(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::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(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::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyDomainLeaveServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(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;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ProtectionSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ProtectionSystem;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->Type;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainServiceId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsGuid(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        
        ::Platform::Guid winRtValue = NodeRT::Utils::GuidFromJs(value);

        wrapper->_instance->DomainServiceId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DomainAccountIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainAccountId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainAccountIdSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsGuid(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        
        ::Platform::Guid winRtValue = NodeRT::Utils::GuidFromJs(value);

        wrapper->_instance->DomainAccountId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyDomainLeaveServiceRequest *wrapper = PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyDomainLeaveServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ UnwrapPlayReadyDomainLeaveServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyDomainLeaveServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyDomainLeaveServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ 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>(PlayReadyDomainLeaveServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyDomainLeaveServiceRequest^ UnwrapPlayReadyDomainLeaveServiceRequest(Local<Value> value)
  {
     return PlayReadyDomainLeaveServiceRequest::Unwrap<PlayReadyDomainLeaveServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyDomainLeaveServiceRequest(Local<Object> exports)
  {
    PlayReadyDomainLeaveServiceRequest::Init(exports);
  }

  class PlayReadyLicenseAcquisitionServiceRequest : 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>("PlayReadyLicenseAcquisitionServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("protectionSystem").ToLocalChecked(), ProtectionSystemGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("type").ToLocalChecked(), TypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainServiceId").ToLocalChecked(), DomainServiceIdGetter, DomainServiceIdSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contentHeader").ToLocalChecked(), ContentHeaderGetter, ContentHeaderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyLicenseAcquisitionServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ 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::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest();
        }
        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());

      PlayReadyLicenseAcquisitionServiceRequest *wrapperInstance = new PlayReadyLicenseAcquisitionServiceRequest(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::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(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::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyLicenseAcquisitionServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(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;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ProtectionSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ProtectionSystem;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->Type;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainServiceId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsGuid(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        
        ::Platform::Guid winRtValue = NodeRT::Utils::GuidFromJs(value);

        wrapper->_instance->DomainServiceId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ContentHeaderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ result = wrapper->_instance->ContentHeader;
        info.GetReturnValue().Set(WrapPlayReadyContentHeader(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ContentHeaderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ winRtValue = dynamic_cast<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->ContentHeader = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseAcquisitionServiceRequest *wrapper = PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ UnwrapPlayReadyLicenseAcquisitionServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyLicenseAcquisitionServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ 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>(PlayReadyLicenseAcquisitionServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseAcquisitionServiceRequest^ UnwrapPlayReadyLicenseAcquisitionServiceRequest(Local<Value> value)
  {
     return PlayReadyLicenseAcquisitionServiceRequest::Unwrap<PlayReadyLicenseAcquisitionServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyLicenseAcquisitionServiceRequest(Local<Object> exports)
  {
    PlayReadyLicenseAcquisitionServiceRequest::Init(exports);
  }

  class PlayReadyMeteringReportServiceRequest : 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>("PlayReadyMeteringReportServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("protectionSystem").ToLocalChecked(), ProtectionSystemGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("type").ToLocalChecked(), TypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("meteringCertificate").ToLocalChecked(), MeteringCertificateGetter, MeteringCertificateSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyMeteringReportServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyMeteringReportServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ 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::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest();
        }
        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());

      PlayReadyMeteringReportServiceRequest *wrapperInstance = new PlayReadyMeteringReportServiceRequest(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::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(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::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyMeteringReportServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(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;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ProtectionSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ProtectionSystem;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->Type;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MeteringCertificateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->MeteringCertificate;
        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 MeteringCertificateSetter(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::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(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->MeteringCertificate = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyMeteringReportServiceRequest *wrapper = PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyMeteringReportServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ UnwrapPlayReadyMeteringReportServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyMeteringReportServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyMeteringReportServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ 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>(PlayReadyMeteringReportServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyMeteringReportServiceRequest^ UnwrapPlayReadyMeteringReportServiceRequest(Local<Value> value)
  {
     return PlayReadyMeteringReportServiceRequest::Unwrap<PlayReadyMeteringReportServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyMeteringReportServiceRequest(Local<Object> exports)
  {
    PlayReadyMeteringReportServiceRequest::Init(exports);
  }

  class PlayReadyRevocationServiceRequest : 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>("PlayReadyRevocationServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("protectionSystem").ToLocalChecked(), ProtectionSystemGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("type").ToLocalChecked(), TypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyRevocationServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyRevocationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ 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::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest();
        }
        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());

      PlayReadyRevocationServiceRequest *wrapperInstance = new PlayReadyRevocationServiceRequest(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::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(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::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyRevocationServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(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;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ProtectionSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ProtectionSystem;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->Type;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadyRevocationServiceRequest *wrapper = PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyRevocationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ UnwrapPlayReadyRevocationServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyRevocationServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyRevocationServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ 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>(PlayReadyRevocationServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyRevocationServiceRequest^ UnwrapPlayReadyRevocationServiceRequest(Local<Value> value)
  {
     return PlayReadyRevocationServiceRequest::Unwrap<PlayReadyRevocationServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyRevocationServiceRequest(Local<Object> exports)
  {
    PlayReadyRevocationServiceRequest::Init(exports);
  }

  class PlayReadyLicenseManagement : 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>("PlayReadyLicenseManagement").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>(DeleteLicenses)).ToLocalChecked();
      Nan::Set(constructor, Nan::New<String>("deleteLicenses").ToLocalChecked(), func);

      Nan::Set(exports, Nan::New<String>("PlayReadyLicenseManagement").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyLicenseManagement(::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^ 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::Media::Protection::PlayReady::PlayReadyLicenseManagement^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^) 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());

      PlayReadyLicenseManagement *wrapperInstance = new PlayReadyLicenseManagement(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::Media::Protection::PlayReady::PlayReadyLicenseManagement^>(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::Media::Protection::PlayReady::PlayReadyLicenseManagement^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyLicenseManagement(winRtInstance));
    }


  

    static void DeleteLicenses(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() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ arg0 = UnwrapPlayReadyContentHeader(info[0]);
          
          op = ::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement::DeleteLicenses(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<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::Media::Protection::PlayReady::PlayReadyLicenseManagement^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyLicenseManagement(::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^ UnwrapPlayReadyLicenseManagement(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyLicenseManagement::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyLicenseManagement(::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^ 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>(PlayReadyLicenseManagement::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseManagement^ UnwrapPlayReadyLicenseManagement(Local<Value> value)
  {
     return PlayReadyLicenseManagement::Unwrap<PlayReadyLicenseManagement>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyLicenseManagement(Local<Object> exports)
  {
    PlayReadyLicenseManagement::Init(exports);
  }

  class IPlayReadyLicense : 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>("IPlayReadyLicense").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "getKIDAtChainDepth", GetKIDAtChainDepth);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("chainDepth").ToLocalChecked(), ChainDepthGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainAccountID").ToLocalChecked(), DomainAccountIDGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("expirationDate").ToLocalChecked(), ExpirationDateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("expireAfterFirstPlay").ToLocalChecked(), ExpireAfterFirstPlayGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("fullyEvaluated").ToLocalChecked(), FullyEvaluatedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("usableForPlay").ToLocalChecked(), UsableForPlayGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IPlayReadyLicense").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IPlayReadyLicense(::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ 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::Media::Protection::PlayReady::IPlayReadyLicense^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyLicense^) 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());

      IPlayReadyLicense *wrapperInstance = new IPlayReadyLicense(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::Media::Protection::PlayReady::IPlayReadyLicense^>(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::Media::Protection::PlayReady::IPlayReadyLicense^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyLicense^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIPlayReadyLicense(winRtInstance));
    }


  
    static void GetKIDAtChainDepth(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info.This()))
      {
        return;
      }

      IPlayReadyLicense *wrapper = IPlayReadyLicense::Unwrap<IPlayReadyLicense>(info.This());

      if (info.Length() == 1
        && info[0]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          
          ::Platform::Guid result;
          result = wrapper->_instance->GetKIDAtChainDepth(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(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 ChainDepthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info.This()))
      {
        return;
      }

      IPlayReadyLicense *wrapper = IPlayReadyLicense::Unwrap<IPlayReadyLicense>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ChainDepth;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainAccountIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info.This()))
      {
        return;
      }

      IPlayReadyLicense *wrapper = IPlayReadyLicense::Unwrap<IPlayReadyLicense>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainAccountID;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ExpirationDateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info.This()))
      {
        return;
      }

      IPlayReadyLicense *wrapper = IPlayReadyLicense::Unwrap<IPlayReadyLicense>(info.This());

      try 
      {
        ::Platform::IBox<::Windows::Foundation::DateTime>^ result = wrapper->_instance->ExpirationDate;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(NodeRT::Utils::DateTimeToJS(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ExpireAfterFirstPlayGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info.This()))
      {
        return;
      }

      IPlayReadyLicense *wrapper = IPlayReadyLicense::Unwrap<IPlayReadyLicense>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ExpireAfterFirstPlay;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FullyEvaluatedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info.This()))
      {
        return;
      }

      IPlayReadyLicense *wrapper = IPlayReadyLicense::Unwrap<IPlayReadyLicense>(info.This());

      try 
      {
        bool result = wrapper->_instance->FullyEvaluated;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UsableForPlayGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>(info.This()))
      {
        return;
      }

      IPlayReadyLicense *wrapper = IPlayReadyLicense::Unwrap<IPlayReadyLicense>(info.This());

      try 
      {
        bool result = wrapper->_instance->UsableForPlay;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIPlayReadyLicense(::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ UnwrapIPlayReadyLicense(Local<Value> value);
  };
  Persistent<FunctionTemplate> IPlayReadyLicense::s_constructorTemplate;

  v8::Local<v8::Value> WrapIPlayReadyLicense(::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ 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>(IPlayReadyLicense::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ UnwrapIPlayReadyLicense(Local<Value> value)
  {
     return IPlayReadyLicense::Unwrap<IPlayReadyLicense>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIPlayReadyLicense(Local<Object> exports)
  {
    IPlayReadyLicense::Init(exports);
  }

  class PlayReadyLicense : 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>("PlayReadyLicense").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "getKIDAtChainDepth", GetKIDAtChainDepth);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("chainDepth").ToLocalChecked(), ChainDepthGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainAccountID").ToLocalChecked(), DomainAccountIDGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("expirationDate").ToLocalChecked(), ExpirationDateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("expireAfterFirstPlay").ToLocalChecked(), ExpireAfterFirstPlayGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("fullyEvaluated").ToLocalChecked(), FullyEvaluatedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("usableForPlay").ToLocalChecked(), UsableForPlayGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyLicense").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyLicense(::Windows::Media::Protection::PlayReady::PlayReadyLicense^ 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::Media::Protection::PlayReady::PlayReadyLicense^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicense^) 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());

      PlayReadyLicense *wrapperInstance = new PlayReadyLicense(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::Media::Protection::PlayReady::PlayReadyLicense^>(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::Media::Protection::PlayReady::PlayReadyLicense^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicense^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyLicense(winRtInstance));
    }


  
    static void GetKIDAtChainDepth(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info.This()))
      {
        return;
      }

      PlayReadyLicense *wrapper = PlayReadyLicense::Unwrap<PlayReadyLicense>(info.This());

      if (info.Length() == 1
        && info[0]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          
          ::Platform::Guid result;
          result = wrapper->_instance->GetKIDAtChainDepth(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(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 ChainDepthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info.This()))
      {
        return;
      }

      PlayReadyLicense *wrapper = PlayReadyLicense::Unwrap<PlayReadyLicense>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ChainDepth;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainAccountIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info.This()))
      {
        return;
      }

      PlayReadyLicense *wrapper = PlayReadyLicense::Unwrap<PlayReadyLicense>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainAccountID;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ExpirationDateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info.This()))
      {
        return;
      }

      PlayReadyLicense *wrapper = PlayReadyLicense::Unwrap<PlayReadyLicense>(info.This());

      try 
      {
        ::Platform::IBox<::Windows::Foundation::DateTime>^ result = wrapper->_instance->ExpirationDate;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(NodeRT::Utils::DateTimeToJS(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ExpireAfterFirstPlayGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info.This()))
      {
        return;
      }

      PlayReadyLicense *wrapper = PlayReadyLicense::Unwrap<PlayReadyLicense>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ExpireAfterFirstPlay;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FullyEvaluatedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info.This()))
      {
        return;
      }

      PlayReadyLicense *wrapper = PlayReadyLicense::Unwrap<PlayReadyLicense>(info.This());

      try 
      {
        bool result = wrapper->_instance->FullyEvaluated;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UsableForPlayGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicense^>(info.This()))
      {
        return;
      }

      PlayReadyLicense *wrapper = PlayReadyLicense::Unwrap<PlayReadyLicense>(info.This());

      try 
      {
        bool result = wrapper->_instance->UsableForPlay;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyLicense^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyLicense(::Windows::Media::Protection::PlayReady::PlayReadyLicense^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyLicense^ UnwrapPlayReadyLicense(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyLicense::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyLicense(::Windows::Media::Protection::PlayReady::PlayReadyLicense^ 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>(PlayReadyLicense::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyLicense^ UnwrapPlayReadyLicense(Local<Value> value)
  {
     return PlayReadyLicense::Unwrap<PlayReadyLicense>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyLicense(Local<Object> exports)
  {
    PlayReadyLicense::Init(exports);
  }

  class PlayReadyLicenseIterable : 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>("PlayReadyLicenseIterable").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "first", First);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyLicenseIterable").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyLicenseIterable(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^ 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::Media::Protection::PlayReady::PlayReadyLicenseIterable^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(info[0])
        && info[1]->IsBoolean())
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ arg0 = UnwrapPlayReadyContentHeader(info[0]);
          bool arg1 = Nan::To<bool>(info[1]).FromMaybe(false);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable(arg0,arg1);
        }
        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());

      PlayReadyLicenseIterable *wrapperInstance = new PlayReadyLicenseIterable(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::Media::Protection::PlayReady::PlayReadyLicenseIterable^>(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::Media::Protection::PlayReady::PlayReadyLicenseIterable^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyLicenseIterable(winRtInstance));
    }


  
    static void First(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseIterable *wrapper = PlayReadyLicenseIterable::Unwrap<PlayReadyLicenseIterable>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Foundation::Collections::IIterator<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>^ result;
          result = wrapper->_instance->First();
          info.GetReturnValue().Set(NodeRT::Collections::IteratorWrapper<::Windows::Media::Protection::PlayReady::IPlayReadyLicense^>::CreateIteratorWrapper(result, 
            [](::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ val) -> Local<Value> {
              return WrapIPlayReadyLicense(val);
            }
          ));
          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::Media::Protection::PlayReady::PlayReadyLicenseIterable^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyLicenseIterable(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^ UnwrapPlayReadyLicenseIterable(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyLicenseIterable::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyLicenseIterable(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^ 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>(PlayReadyLicenseIterable::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterable^ UnwrapPlayReadyLicenseIterable(Local<Value> value)
  {
     return PlayReadyLicenseIterable::Unwrap<PlayReadyLicenseIterable>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyLicenseIterable(Local<Object> exports)
  {
    PlayReadyLicenseIterable::Init(exports);
  }

  class PlayReadyLicenseIterator : 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>("PlayReadyLicenseIterator").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "moveNext", MoveNext);
      Nan::SetPrototypeMethod(localRef, "getMany", GetMany);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("current").ToLocalChecked(), CurrentGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hasCurrent").ToLocalChecked(), HasCurrentGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyLicenseIterator").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyLicenseIterator(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ 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::Media::Protection::PlayReady::PlayReadyLicenseIterator^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^) 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());

      PlayReadyLicenseIterator *wrapperInstance = new PlayReadyLicenseIterator(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::Media::Protection::PlayReady::PlayReadyLicenseIterator^>(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::Media::Protection::PlayReady::PlayReadyLicenseIterator^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyLicenseIterator(winRtInstance));
    }


  
    static void MoveNext(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseIterator *wrapper = PlayReadyLicenseIterator::Unwrap<PlayReadyLicenseIterator>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          bool result;
          result = wrapper->_instance->MoveNext();
          info.GetReturnValue().Set(Nan::New<Boolean>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void GetMany(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;
      Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Not implemented")));
    }



    static void CurrentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseIterator *wrapper = PlayReadyLicenseIterator::Unwrap<PlayReadyLicenseIterator>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::IPlayReadyLicense^ result = wrapper->_instance->Current;
        info.GetReturnValue().Set(WrapIPlayReadyLicense(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void HasCurrentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseIterator *wrapper = PlayReadyLicenseIterator::Unwrap<PlayReadyLicenseIterator>(info.This());

      try 
      {
        bool result = wrapper->_instance->HasCurrent;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyLicenseIterator(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ UnwrapPlayReadyLicenseIterator(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyLicenseIterator::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyLicenseIterator(::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ 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>(PlayReadyLicenseIterator::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseIterator^ UnwrapPlayReadyLicenseIterator(Local<Value> value)
  {
     return PlayReadyLicenseIterator::Unwrap<PlayReadyLicenseIterator>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyLicenseIterator(Local<Object> exports)
  {
    PlayReadyLicenseIterator::Init(exports);
  }

  class IPlayReadyDomain : 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>("IPlayReadyDomain").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("accountId").ToLocalChecked(), AccountIdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainJoinUrl").ToLocalChecked(), DomainJoinUrlGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("friendlyName").ToLocalChecked(), FriendlyNameGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("revision").ToLocalChecked(), RevisionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("serviceId").ToLocalChecked(), ServiceIdGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IPlayReadyDomain").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IPlayReadyDomain(::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ 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::Media::Protection::PlayReady::IPlayReadyDomain^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyDomain^) 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());

      IPlayReadyDomain *wrapperInstance = new IPlayReadyDomain(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::Media::Protection::PlayReady::IPlayReadyDomain^>(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::Media::Protection::PlayReady::IPlayReadyDomain^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyDomain^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIPlayReadyDomain(winRtInstance));
    }


  



    static void AccountIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>(info.This()))
      {
        return;
      }

      IPlayReadyDomain *wrapper = IPlayReadyDomain::Unwrap<IPlayReadyDomain>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->AccountId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainJoinUrlGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>(info.This()))
      {
        return;
      }

      IPlayReadyDomain *wrapper = IPlayReadyDomain::Unwrap<IPlayReadyDomain>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->DomainJoinUrl;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FriendlyNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>(info.This()))
      {
        return;
      }

      IPlayReadyDomain *wrapper = IPlayReadyDomain::Unwrap<IPlayReadyDomain>(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 RevisionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>(info.This()))
      {
        return;
      }

      IPlayReadyDomain *wrapper = IPlayReadyDomain::Unwrap<IPlayReadyDomain>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->Revision;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ServiceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>(info.This()))
      {
        return;
      }

      IPlayReadyDomain *wrapper = IPlayReadyDomain::Unwrap<IPlayReadyDomain>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ServiceId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIPlayReadyDomain(::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ UnwrapIPlayReadyDomain(Local<Value> value);
  };
  Persistent<FunctionTemplate> IPlayReadyDomain::s_constructorTemplate;

  v8::Local<v8::Value> WrapIPlayReadyDomain(::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ 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>(IPlayReadyDomain::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ UnwrapIPlayReadyDomain(Local<Value> value)
  {
     return IPlayReadyDomain::Unwrap<IPlayReadyDomain>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIPlayReadyDomain(Local<Object> exports)
  {
    IPlayReadyDomain::Init(exports);
  }

  class PlayReadyDomain : 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>("PlayReadyDomain").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("accountId").ToLocalChecked(), AccountIdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainJoinUrl").ToLocalChecked(), DomainJoinUrlGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("friendlyName").ToLocalChecked(), FriendlyNameGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("revision").ToLocalChecked(), RevisionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("serviceId").ToLocalChecked(), ServiceIdGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyDomain").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyDomain(::Windows::Media::Protection::PlayReady::PlayReadyDomain^ 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::Media::Protection::PlayReady::PlayReadyDomain^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomain^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomain^) 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());

      PlayReadyDomain *wrapperInstance = new PlayReadyDomain(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::Media::Protection::PlayReady::PlayReadyDomain^>(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::Media::Protection::PlayReady::PlayReadyDomain^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomain^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyDomain(winRtInstance));
    }


  



    static void AccountIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomain^>(info.This()))
      {
        return;
      }

      PlayReadyDomain *wrapper = PlayReadyDomain::Unwrap<PlayReadyDomain>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->AccountId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainJoinUrlGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomain^>(info.This()))
      {
        return;
      }

      PlayReadyDomain *wrapper = PlayReadyDomain::Unwrap<PlayReadyDomain>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->DomainJoinUrl;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FriendlyNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomain^>(info.This()))
      {
        return;
      }

      PlayReadyDomain *wrapper = PlayReadyDomain::Unwrap<PlayReadyDomain>(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 RevisionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomain^>(info.This()))
      {
        return;
      }

      PlayReadyDomain *wrapper = PlayReadyDomain::Unwrap<PlayReadyDomain>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->Revision;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ServiceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomain^>(info.This()))
      {
        return;
      }

      PlayReadyDomain *wrapper = PlayReadyDomain::Unwrap<PlayReadyDomain>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ServiceId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyDomain^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyDomain(::Windows::Media::Protection::PlayReady::PlayReadyDomain^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyDomain^ UnwrapPlayReadyDomain(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyDomain::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyDomain(::Windows::Media::Protection::PlayReady::PlayReadyDomain^ 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>(PlayReadyDomain::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyDomain^ UnwrapPlayReadyDomain(Local<Value> value)
  {
     return PlayReadyDomain::Unwrap<PlayReadyDomain>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyDomain(Local<Object> exports)
  {
    PlayReadyDomain::Init(exports);
  }

  class PlayReadyDomainIterable : 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>("PlayReadyDomainIterable").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "first", First);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyDomainIterable").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyDomainIterable(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^ 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::Media::Protection::PlayReady::PlayReadyDomainIterable^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && NodeRT::Utils::IsGuid(info[0]))
      {
        try
        {
          ::Platform::Guid arg0 = NodeRT::Utils::GuidFromJs(info[0]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable(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());

      PlayReadyDomainIterable *wrapperInstance = new PlayReadyDomainIterable(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::Media::Protection::PlayReady::PlayReadyDomainIterable^>(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::Media::Protection::PlayReady::PlayReadyDomainIterable^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyDomainIterable(winRtInstance));
    }


  
    static void First(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^>(info.This()))
      {
        return;
      }

      PlayReadyDomainIterable *wrapper = PlayReadyDomainIterable::Unwrap<PlayReadyDomainIterable>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Foundation::Collections::IIterator<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>^ result;
          result = wrapper->_instance->First();
          info.GetReturnValue().Set(NodeRT::Collections::IteratorWrapper<::Windows::Media::Protection::PlayReady::IPlayReadyDomain^>::CreateIteratorWrapper(result, 
            [](::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ val) -> Local<Value> {
              return WrapIPlayReadyDomain(val);
            }
          ));
          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::Media::Protection::PlayReady::PlayReadyDomainIterable^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyDomainIterable(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^ UnwrapPlayReadyDomainIterable(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyDomainIterable::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyDomainIterable(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^ 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>(PlayReadyDomainIterable::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterable^ UnwrapPlayReadyDomainIterable(Local<Value> value)
  {
     return PlayReadyDomainIterable::Unwrap<PlayReadyDomainIterable>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyDomainIterable(Local<Object> exports)
  {
    PlayReadyDomainIterable::Init(exports);
  }

  class PlayReadyDomainIterator : 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>("PlayReadyDomainIterator").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "moveNext", MoveNext);
      Nan::SetPrototypeMethod(localRef, "getMany", GetMany);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("current").ToLocalChecked(), CurrentGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hasCurrent").ToLocalChecked(), HasCurrentGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyDomainIterator").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyDomainIterator(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ 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::Media::Protection::PlayReady::PlayReadyDomainIterator^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^) 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());

      PlayReadyDomainIterator *wrapperInstance = new PlayReadyDomainIterator(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::Media::Protection::PlayReady::PlayReadyDomainIterator^>(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::Media::Protection::PlayReady::PlayReadyDomainIterator^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyDomainIterator(winRtInstance));
    }


  
    static void MoveNext(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^>(info.This()))
      {
        return;
      }

      PlayReadyDomainIterator *wrapper = PlayReadyDomainIterator::Unwrap<PlayReadyDomainIterator>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          bool result;
          result = wrapper->_instance->MoveNext();
          info.GetReturnValue().Set(Nan::New<Boolean>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void GetMany(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;
      Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Not implemented")));
    }



    static void CurrentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^>(info.This()))
      {
        return;
      }

      PlayReadyDomainIterator *wrapper = PlayReadyDomainIterator::Unwrap<PlayReadyDomainIterator>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::IPlayReadyDomain^ result = wrapper->_instance->Current;
        info.GetReturnValue().Set(WrapIPlayReadyDomain(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void HasCurrentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^>(info.This()))
      {
        return;
      }

      PlayReadyDomainIterator *wrapper = PlayReadyDomainIterator::Unwrap<PlayReadyDomainIterator>(info.This());

      try 
      {
        bool result = wrapper->_instance->HasCurrent;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyDomainIterator(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ UnwrapPlayReadyDomainIterator(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyDomainIterator::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyDomainIterator(::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ 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>(PlayReadyDomainIterator::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyDomainIterator^ UnwrapPlayReadyDomainIterator(Local<Value> value)
  {
     return PlayReadyDomainIterator::Unwrap<PlayReadyDomainIterator>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyDomainIterator(Local<Object> exports)
  {
    PlayReadyDomainIterator::Init(exports);
  }

  class PlayReadyStatics : 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>("PlayReadyStatics").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "checkSupportedHardware", CheckSupportedHardware);
      Nan::SetAccessor(constructor, Nan::New<String>("domainJoinServiceRequestType").ToLocalChecked(), DomainJoinServiceRequestTypeGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("domainLeaveServiceRequestType").ToLocalChecked(), DomainLeaveServiceRequestTypeGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("individualizationServiceRequestType").ToLocalChecked(), IndividualizationServiceRequestTypeGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("licenseAcquirerServiceRequestType").ToLocalChecked(), LicenseAcquirerServiceRequestTypeGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("mediaProtectionSystemId").ToLocalChecked(), MediaProtectionSystemIdGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("meteringReportServiceRequestType").ToLocalChecked(), MeteringReportServiceRequestTypeGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("playReadySecurityVersion").ToLocalChecked(), PlayReadySecurityVersionGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("revocationServiceRequestType").ToLocalChecked(), RevocationServiceRequestTypeGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("playReadyCertificateSecurityLevel").ToLocalChecked(), PlayReadyCertificateSecurityLevelGetter);
      Nan::SetAccessor(constructor, Nan::New<String>("secureStopServiceRequestType").ToLocalChecked(), SecureStopServiceRequestTypeGetter);

      Nan::Set(exports, Nan::New<String>("PlayReadyStatics").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyStatics(::Windows::Media::Protection::PlayReady::PlayReadyStatics^ 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::Media::Protection::PlayReady::PlayReadyStatics^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyStatics^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyStatics^) 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());

      PlayReadyStatics *wrapperInstance = new PlayReadyStatics(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::Media::Protection::PlayReady::PlayReadyStatics^>(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::Media::Protection::PlayReady::PlayReadyStatics^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyStatics^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyStatics(winRtInstance));
    }


  


    static void CheckSupportedHardware(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadyHardwareDRMFeatures arg0 = static_cast<::Windows::Media::Protection::PlayReady::PlayReadyHardwareDRMFeatures>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::CheckSupportedHardware(arg0);
          info.GetReturnValue().Set(Nan::New<Boolean>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }


    static void DomainJoinServiceRequestTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::DomainJoinServiceRequestType;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainLeaveServiceRequestTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::DomainLeaveServiceRequestType;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IndividualizationServiceRequestTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::IndividualizationServiceRequestType;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LicenseAcquirerServiceRequestTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::LicenseAcquirerServiceRequestType;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MediaProtectionSystemIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::MediaProtectionSystemId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MeteringReportServiceRequestTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::MeteringReportServiceRequestType;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PlayReadySecurityVersionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        unsigned int result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::PlayReadySecurityVersion;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void RevocationServiceRequestTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::RevocationServiceRequestType;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PlayReadyCertificateSecurityLevelGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        unsigned int result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::PlayReadyCertificateSecurityLevel;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SecureStopServiceRequestTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;

      try 
      {
        ::Platform::Guid result = ::Windows::Media::Protection::PlayReady::PlayReadyStatics::SecureStopServiceRequestType;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    

  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyStatics^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyStatics(::Windows::Media::Protection::PlayReady::PlayReadyStatics^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyStatics^ UnwrapPlayReadyStatics(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyStatics::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyStatics(::Windows::Media::Protection::PlayReady::PlayReadyStatics^ 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>(PlayReadyStatics::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyStatics^ UnwrapPlayReadyStatics(Local<Value> value)
  {
     return PlayReadyStatics::Unwrap<PlayReadyStatics>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyStatics(Local<Object> exports)
  {
    PlayReadyStatics::Init(exports);
  }

  class PlayReadySecureStopServiceRequest : 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>("PlayReadySecureStopServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("protectionSystem").ToLocalChecked(), ProtectionSystemGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("type").ToLocalChecked(), TypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("publisherCertificate").ToLocalChecked(), PublisherCertificateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("sessionID").ToLocalChecked(), SessionIDGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("startTime").ToLocalChecked(), StartTimeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("stopped").ToLocalChecked(), StoppedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("updateTime").ToLocalChecked(), UpdateTimeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadySecureStopServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ 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::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && NodeRT::Utils::IsGuid(info[0])
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Platform::Guid arg0 = NodeRT::Utils::GuidFromJs(info[0]);
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest(arg0,arg1);
        }
        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());

      PlayReadySecureStopServiceRequest *wrapperInstance = new PlayReadySecureStopServiceRequest(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::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(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::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadySecureStopServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(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;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ProtectionSystemGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->ProtectionSystem;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->Type;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PublisherCertificateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->PublisherCertificate;
        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 SessionIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->SessionID;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void StartTimeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::DateTime result = wrapper->_instance->StartTime;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void StoppedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        bool result = wrapper->_instance->Stopped;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UpdateTimeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::DateTime result = wrapper->_instance->UpdateTime;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopServiceRequest *wrapper = PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ UnwrapPlayReadySecureStopServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadySecureStopServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ 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>(PlayReadySecureStopServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadySecureStopServiceRequest^ UnwrapPlayReadySecureStopServiceRequest(Local<Value> value)
  {
     return PlayReadySecureStopServiceRequest::Unwrap<PlayReadySecureStopServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadySecureStopServiceRequest(Local<Object> exports)
  {
    PlayReadySecureStopServiceRequest::Init(exports);
  }

  class PlayReadySecureStopIterable : 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>("PlayReadySecureStopIterable").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "first", First);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadySecureStopIterable").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadySecureStopIterable(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^ 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::Media::Protection::PlayReady::PlayReadySecureStopIterable^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable(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());

      PlayReadySecureStopIterable *wrapperInstance = new PlayReadySecureStopIterable(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::Media::Protection::PlayReady::PlayReadySecureStopIterable^>(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::Media::Protection::PlayReady::PlayReadySecureStopIterable^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadySecureStopIterable(winRtInstance));
    }


  
    static void First(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopIterable *wrapper = PlayReadySecureStopIterable::Unwrap<PlayReadySecureStopIterable>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Foundation::Collections::IIterator<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>^ result;
          result = wrapper->_instance->First();
          info.GetReturnValue().Set(NodeRT::Collections::IteratorWrapper<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>::CreateIteratorWrapper(result, 
            [](::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ val) -> Local<Value> {
              return WrapIPlayReadySecureStopServiceRequest(val);
            }
          ));
          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::Media::Protection::PlayReady::PlayReadySecureStopIterable^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadySecureStopIterable(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^ UnwrapPlayReadySecureStopIterable(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadySecureStopIterable::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadySecureStopIterable(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^ 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>(PlayReadySecureStopIterable::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterable^ UnwrapPlayReadySecureStopIterable(Local<Value> value)
  {
     return PlayReadySecureStopIterable::Unwrap<PlayReadySecureStopIterable>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadySecureStopIterable(Local<Object> exports)
  {
    PlayReadySecureStopIterable::Init(exports);
  }

  class PlayReadySecureStopIterator : 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>("PlayReadySecureStopIterator").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "moveNext", MoveNext);
      Nan::SetPrototypeMethod(localRef, "getMany", GetMany);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("current").ToLocalChecked(), CurrentGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hasCurrent").ToLocalChecked(), HasCurrentGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadySecureStopIterator").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadySecureStopIterator(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ 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::Media::Protection::PlayReady::PlayReadySecureStopIterator^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^) 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());

      PlayReadySecureStopIterator *wrapperInstance = new PlayReadySecureStopIterator(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::Media::Protection::PlayReady::PlayReadySecureStopIterator^>(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::Media::Protection::PlayReady::PlayReadySecureStopIterator^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadySecureStopIterator(winRtInstance));
    }


  
    static void MoveNext(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopIterator *wrapper = PlayReadySecureStopIterator::Unwrap<PlayReadySecureStopIterator>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          bool result;
          result = wrapper->_instance->MoveNext();
          info.GetReturnValue().Set(Nan::New<Boolean>(result));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void GetMany(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;
      Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Not implemented")));
    }



    static void CurrentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopIterator *wrapper = PlayReadySecureStopIterator::Unwrap<PlayReadySecureStopIterator>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ result = wrapper->_instance->Current;
        info.GetReturnValue().Set(WrapIPlayReadySecureStopServiceRequest(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void HasCurrentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^>(info.This()))
      {
        return;
      }

      PlayReadySecureStopIterator *wrapper = PlayReadySecureStopIterator::Unwrap<PlayReadySecureStopIterator>(info.This());

      try 
      {
        bool result = wrapper->_instance->HasCurrent;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadySecureStopIterator(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ UnwrapPlayReadySecureStopIterator(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadySecureStopIterator::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadySecureStopIterator(::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ 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>(PlayReadySecureStopIterator::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadySecureStopIterator^ UnwrapPlayReadySecureStopIterator(Local<Value> value)
  {
     return PlayReadySecureStopIterator::Unwrap<PlayReadySecureStopIterator>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadySecureStopIterator(Local<Object> exports)
  {
    PlayReadySecureStopIterator::Init(exports);
  }

  class PlayReadyITADataGenerator : 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>("PlayReadyITADataGenerator").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "generateData", GenerateData);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyITADataGenerator").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyITADataGenerator(::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ 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::Media::Protection::PlayReady::PlayReadyITADataGenerator^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator();
        }
        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());

      PlayReadyITADataGenerator *wrapperInstance = new PlayReadyITADataGenerator(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::Media::Protection::PlayReady::PlayReadyITADataGenerator^>(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::Media::Protection::PlayReady::PlayReadyITADataGenerator^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyITADataGenerator(winRtInstance));
    }


  
    static void GenerateData(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^>(info.This()))
      {
        return;
      }

      PlayReadyITADataGenerator *wrapper = PlayReadyITADataGenerator::Unwrap<PlayReadyITADataGenerator>(info.This());

      if (info.Length() == 4
        && NodeRT::Utils::IsGuid(info[0])
        && info[1]->IsUint32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IPropertySet^>(info[2])
        && info[3]->IsInt32())
      {
        try
        {
          ::Platform::Guid arg0 = NodeRT::Utils::GuidFromJs(info[0]);
          unsigned int arg1 = static_cast<unsigned int>(Nan::To<uint32_t>(info[1]).FromMaybe(0));
          ::Windows::Foundation::Collections::IPropertySet^ arg2 = dynamic_cast<::Windows::Foundation::Collections::IPropertySet^>(NodeRT::Utils::GetObjectInstance(info[2]));
          ::Windows::Media::Protection::PlayReady::PlayReadyITADataFormat arg3 = static_cast<::Windows::Media::Protection::PlayReady::PlayReadyITADataFormat>(Nan::To<int32_t>(info[3]).FromMaybe(0));
          
          ::Platform::Array<unsigned char>^ result;
          result = wrapper->_instance->GenerateData(arg0, arg1, arg2, arg3);
          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;
      }
    }





  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyITADataGenerator(::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ UnwrapPlayReadyITADataGenerator(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyITADataGenerator::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyITADataGenerator(::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ 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>(PlayReadyITADataGenerator::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyITADataGenerator^ UnwrapPlayReadyITADataGenerator(Local<Value> value)
  {
     return PlayReadyITADataGenerator::Unwrap<PlayReadyITADataGenerator>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyITADataGenerator(Local<Object> exports)
  {
    PlayReadyITADataGenerator::Init(exports);
  }

  class IPlayReadyLicenseSession : 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>("IPlayReadyLicenseSession").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "createLAServiceRequest", CreateLAServiceRequest);
      Nan::SetPrototypeMethod(localRef, "configureMediaProtectionManager", ConfigureMediaProtectionManager);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IPlayReadyLicenseSession").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IPlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ 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::Media::Protection::PlayReady::IPlayReadyLicenseSession^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^) 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());

      IPlayReadyLicenseSession *wrapperInstance = new IPlayReadyLicenseSession(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::Media::Protection::PlayReady::IPlayReadyLicenseSession^>(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::Media::Protection::PlayReady::IPlayReadyLicenseSession^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIPlayReadyLicenseSession(winRtInstance));
    }


  
    static void CreateLAServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^>(info.This()))
      {
        return;
      }

      IPlayReadyLicenseSession *wrapper = IPlayReadyLicenseSession::Unwrap<IPlayReadyLicenseSession>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ result;
          result = wrapper->_instance->CreateLAServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyLicenseAcquisitionServiceRequest(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 ConfigureMediaProtectionManager(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^>(info.This()))
      {
        return;
      }

      IPlayReadyLicenseSession *wrapper = IPlayReadyLicenseSession::Unwrap<IPlayReadyLicenseSession>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::MediaProtectionManager^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::MediaProtectionManager^ arg0 = dynamic_cast<::Windows::Media::Protection::MediaProtectionManager^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          wrapper->_instance->ConfigureMediaProtectionManager(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;
      }
    }





  private:
    ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIPlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ UnwrapIPlayReadyLicenseSession(Local<Value> value);
  };
  Persistent<FunctionTemplate> IPlayReadyLicenseSession::s_constructorTemplate;

  v8::Local<v8::Value> WrapIPlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ 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>(IPlayReadyLicenseSession::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseSession^ UnwrapIPlayReadyLicenseSession(Local<Value> value)
  {
     return IPlayReadyLicenseSession::Unwrap<IPlayReadyLicenseSession>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIPlayReadyLicenseSession(Local<Object> exports)
  {
    IPlayReadyLicenseSession::Init(exports);
  }

  class PlayReadyLicenseSession : 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>("PlayReadyLicenseSession").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "createLAServiceRequest", CreateLAServiceRequest);
      Nan::SetPrototypeMethod(localRef, "configureMediaProtectionManager", ConfigureMediaProtectionManager);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PlayReadyLicenseSession").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ 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::Media::Protection::PlayReady::PlayReadyLicenseSession^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IPropertySet^>(info[0]))
      {
        try
        {
          ::Windows::Foundation::Collections::IPropertySet^ arg0 = dynamic_cast<::Windows::Foundation::Collections::IPropertySet^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession(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());

      PlayReadyLicenseSession *wrapperInstance = new PlayReadyLicenseSession(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::Media::Protection::PlayReady::PlayReadyLicenseSession^>(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::Media::Protection::PlayReady::PlayReadyLicenseSession^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPlayReadyLicenseSession(winRtInstance));
    }


  
    static void CreateLAServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseSession *wrapper = PlayReadyLicenseSession::Unwrap<PlayReadyLicenseSession>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ result;
          result = wrapper->_instance->CreateLAServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyLicenseAcquisitionServiceRequest(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 ConfigureMediaProtectionManager(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^>(info.This()))
      {
        return;
      }

      PlayReadyLicenseSession *wrapper = PlayReadyLicenseSession::Unwrap<PlayReadyLicenseSession>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::MediaProtectionManager^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::MediaProtectionManager^ arg0 = dynamic_cast<::Windows::Media::Protection::MediaProtectionManager^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          wrapper->_instance->ConfigureMediaProtectionManager(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;
      }
    }





  private:
    ::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ UnwrapPlayReadyLicenseSession(Local<Value> value);
  };
  Persistent<FunctionTemplate> PlayReadyLicenseSession::s_constructorTemplate;

  v8::Local<v8::Value> WrapPlayReadyLicenseSession(::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ 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>(PlayReadyLicenseSession::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::PlayReadyLicenseSession^ UnwrapPlayReadyLicenseSession(Local<Value> value)
  {
     return PlayReadyLicenseSession::Unwrap<PlayReadyLicenseSession>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPlayReadyLicenseSession(Local<Object> exports)
  {
    PlayReadyLicenseSession::Init(exports);
  }

  class INDDownloadEngine : 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>("INDDownloadEngine").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "open", Open);
      Nan::SetPrototypeMethod(localRef, "pause", Pause);
      Nan::SetPrototypeMethod(localRef, "resume", Resume);
      Nan::SetPrototypeMethod(localRef, "close", Close);
      Nan::SetPrototypeMethod(localRef, "seek", Seek);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("bufferFullMaxThresholdInSamples").ToLocalChecked(), BufferFullMaxThresholdInSamplesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("bufferFullMinThresholdInSamples").ToLocalChecked(), BufferFullMinThresholdInSamplesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("canSeek").ToLocalChecked(), CanSeekGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("notifier").ToLocalChecked(), NotifierGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDDownloadEngine").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDDownloadEngine(::Windows::Media::Protection::PlayReady::INDDownloadEngine^ 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::Media::Protection::PlayReady::INDDownloadEngine^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDDownloadEngine^) 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());

      INDDownloadEngine *wrapperInstance = new INDDownloadEngine(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::Media::Protection::PlayReady::INDDownloadEngine^>(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::Media::Protection::PlayReady::INDDownloadEngine^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDDownloadEngine^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDDownloadEngine(winRtInstance));
    }


  
    static void Open(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[0])
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Windows::Foundation::Uri^ arg0 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          wrapper->_instance->Open(arg0, arg1);
          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 Pause(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->Pause();
          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 Resume(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->Resume();
          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 Close(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->Close();
          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 Seek(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          ::Windows::Foundation::TimeSpan arg0 = NodeRT::Utils::TimeSpanFromMilli(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          wrapper->_instance->Seek(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 BufferFullMaxThresholdInSamplesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->BufferFullMaxThresholdInSamples;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void BufferFullMinThresholdInSamplesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->BufferFullMinThresholdInSamples;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CanSeekGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      try 
      {
        bool result = wrapper->_instance->CanSeek;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void NotifierGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info.This()))
      {
        return;
      }

      INDDownloadEngine *wrapper = INDDownloadEngine::Unwrap<INDDownloadEngine>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ result = wrapper->_instance->Notifier;
        info.GetReturnValue().Set(WrapNDDownloadEngineNotifier(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDDownloadEngine^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDDownloadEngine(::Windows::Media::Protection::PlayReady::INDDownloadEngine^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDDownloadEngine^ UnwrapINDDownloadEngine(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDDownloadEngine::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDDownloadEngine(::Windows::Media::Protection::PlayReady::INDDownloadEngine^ 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>(INDDownloadEngine::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDDownloadEngine^ UnwrapINDDownloadEngine(Local<Value> value)
  {
     return INDDownloadEngine::Unwrap<INDDownloadEngine>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDDownloadEngine(Local<Object> exports)
  {
    INDDownloadEngine::Init(exports);
  }

  class NDDownloadEngineNotifier : 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>("NDDownloadEngineNotifier").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "onStreamOpened", OnStreamOpened);
      Nan::SetPrototypeMethod(localRef, "onPlayReadyObjectReceived", OnPlayReadyObjectReceived);
      Nan::SetPrototypeMethod(localRef, "onContentIDReceived", OnContentIDReceived);
      Nan::SetPrototypeMethod(localRef, "onDataReceived", OnDataReceived);
      Nan::SetPrototypeMethod(localRef, "onEndOfStream", OnEndOfStream);
      Nan::SetPrototypeMethod(localRef, "onNetworkError", OnNetworkError);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NDDownloadEngineNotifier").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ 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::Media::Protection::PlayReady::NDDownloadEngineNotifier^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier();
        }
        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());

      NDDownloadEngineNotifier *wrapperInstance = new NDDownloadEngineNotifier(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::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(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::Media::Protection::PlayReady::NDDownloadEngineNotifier^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNDDownloadEngineNotifier(winRtInstance));
    }


  
    static void OnStreamOpened(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      NDDownloadEngineNotifier *wrapper = NDDownloadEngineNotifier::Unwrap<NDDownloadEngineNotifier>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->OnStreamOpened();
          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 OnPlayReadyObjectReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      NDDownloadEngineNotifier *wrapper = NDDownloadEngineNotifier::Unwrap<NDDownloadEngineNotifier>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          wrapper->_instance->OnPlayReadyObjectReceived(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 OnContentIDReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      NDDownloadEngineNotifier *wrapper = NDDownloadEngineNotifier::Unwrap<NDDownloadEngineNotifier>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ arg0 = UnwrapINDLicenseFetchDescriptor(info[0]);
          
          wrapper->_instance->OnContentIDReceived(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 OnDataReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      NDDownloadEngineNotifier *wrapper = NDDownloadEngineNotifier::Unwrap<NDDownloadEngineNotifier>(info.This());

      if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && info[1]->IsUint32())
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          unsigned int arg1 = static_cast<unsigned int>(Nan::To<uint32_t>(info[1]).FromMaybe(0));
          
          wrapper->_instance->OnDataReceived(arg0, arg1);
          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 OnEndOfStream(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      NDDownloadEngineNotifier *wrapper = NDDownloadEngineNotifier::Unwrap<NDDownloadEngineNotifier>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->OnEndOfStream();
          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 OnNetworkError(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      NDDownloadEngineNotifier *wrapper = NDDownloadEngineNotifier::Unwrap<NDDownloadEngineNotifier>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->OnNetworkError();
          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::Media::Protection::PlayReady::NDDownloadEngineNotifier^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ UnwrapNDDownloadEngineNotifier(Local<Value> value);
  };
  Persistent<FunctionTemplate> NDDownloadEngineNotifier::s_constructorTemplate;

  v8::Local<v8::Value> WrapNDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ 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>(NDDownloadEngineNotifier::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::NDDownloadEngineNotifier^ UnwrapNDDownloadEngineNotifier(Local<Value> value)
  {
     return NDDownloadEngineNotifier::Unwrap<NDDownloadEngineNotifier>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNDDownloadEngineNotifier(Local<Object> exports)
  {
    NDDownloadEngineNotifier::Init(exports);
  }

  class INDDownloadEngineNotifier : 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>("INDDownloadEngineNotifier").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "onStreamOpened", OnStreamOpened);
      Nan::SetPrototypeMethod(localRef, "onPlayReadyObjectReceived", OnPlayReadyObjectReceived);
      Nan::SetPrototypeMethod(localRef, "onContentIDReceived", OnContentIDReceived);
      Nan::SetPrototypeMethod(localRef, "onDataReceived", OnDataReceived);
      Nan::SetPrototypeMethod(localRef, "onEndOfStream", OnEndOfStream);
      Nan::SetPrototypeMethod(localRef, "onNetworkError", OnNetworkError);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDDownloadEngineNotifier").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^ 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::Media::Protection::PlayReady::INDDownloadEngineNotifier^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^) 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());

      INDDownloadEngineNotifier *wrapperInstance = new INDDownloadEngineNotifier(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::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(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::Media::Protection::PlayReady::INDDownloadEngineNotifier^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDDownloadEngineNotifier(winRtInstance));
    }


  
    static void OnStreamOpened(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      INDDownloadEngineNotifier *wrapper = INDDownloadEngineNotifier::Unwrap<INDDownloadEngineNotifier>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->OnStreamOpened();
          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 OnPlayReadyObjectReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      INDDownloadEngineNotifier *wrapper = INDDownloadEngineNotifier::Unwrap<INDDownloadEngineNotifier>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          wrapper->_instance->OnPlayReadyObjectReceived(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 OnContentIDReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      INDDownloadEngineNotifier *wrapper = INDDownloadEngineNotifier::Unwrap<INDDownloadEngineNotifier>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ arg0 = UnwrapINDLicenseFetchDescriptor(info[0]);
          
          wrapper->_instance->OnContentIDReceived(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 OnDataReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      INDDownloadEngineNotifier *wrapper = INDDownloadEngineNotifier::Unwrap<INDDownloadEngineNotifier>(info.This());

      if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && info[1]->IsUint32())
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          unsigned int arg1 = static_cast<unsigned int>(Nan::To<uint32_t>(info[1]).FromMaybe(0));
          
          wrapper->_instance->OnDataReceived(arg0, arg1);
          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 OnEndOfStream(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      INDDownloadEngineNotifier *wrapper = INDDownloadEngineNotifier::Unwrap<INDDownloadEngineNotifier>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->OnEndOfStream();
          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 OnNetworkError(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^>(info.This()))
      {
        return;
      }

      INDDownloadEngineNotifier *wrapper = INDDownloadEngineNotifier::Unwrap<INDDownloadEngineNotifier>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->OnNetworkError();
          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::Media::Protection::PlayReady::INDDownloadEngineNotifier^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^ UnwrapINDDownloadEngineNotifier(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDDownloadEngineNotifier::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDDownloadEngineNotifier(::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^ 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>(INDDownloadEngineNotifier::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDDownloadEngineNotifier^ UnwrapINDDownloadEngineNotifier(Local<Value> value)
  {
     return INDDownloadEngineNotifier::Unwrap<INDDownloadEngineNotifier>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDDownloadEngineNotifier(Local<Object> exports)
  {
    INDDownloadEngineNotifier::Init(exports);
  }

  class INDLicenseFetchDescriptor : 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>("INDLicenseFetchDescriptor").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contentID").ToLocalChecked(), ContentIDGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contentIDType").ToLocalChecked(), ContentIDTypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("licenseFetchChallengeCustomData").ToLocalChecked(), LicenseFetchChallengeCustomDataGetter, LicenseFetchChallengeCustomDataSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDLicenseFetchDescriptor").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ 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::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^) 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());

      INDLicenseFetchDescriptor *wrapperInstance = new INDLicenseFetchDescriptor(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::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(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::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDLicenseFetchDescriptor(winRtInstance));
    }


  



    static void ContentIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      INDLicenseFetchDescriptor *wrapper = INDLicenseFetchDescriptor::Unwrap<INDLicenseFetchDescriptor>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->ContentID;
        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 ContentIDTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      INDLicenseFetchDescriptor *wrapper = INDLicenseFetchDescriptor::Unwrap<INDLicenseFetchDescriptor>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::NDContentIDType result = wrapper->_instance->ContentIDType;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LicenseFetchChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      INDLicenseFetchDescriptor *wrapper = INDLicenseFetchDescriptor::Unwrap<INDLicenseFetchDescriptor>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::INDCustomData^ result = wrapper->_instance->LicenseFetchChallengeCustomData;
        info.GetReturnValue().Set(WrapINDCustomData(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LicenseFetchChallengeCustomDataSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      INDLicenseFetchDescriptor *wrapper = INDLicenseFetchDescriptor::Unwrap<INDLicenseFetchDescriptor>(info.This());

      try 
      {
        
        ::Windows::Media::Protection::PlayReady::INDCustomData^ winRtValue = dynamic_cast<::Windows::Media::Protection::PlayReady::INDCustomData^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->LicenseFetchChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ UnwrapINDLicenseFetchDescriptor(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDLicenseFetchDescriptor::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ 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>(INDLicenseFetchDescriptor::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ UnwrapINDLicenseFetchDescriptor(Local<Value> value)
  {
     return INDLicenseFetchDescriptor::Unwrap<INDLicenseFetchDescriptor>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDLicenseFetchDescriptor(Local<Object> exports)
  {
    INDLicenseFetchDescriptor::Init(exports);
  }

  class INDCustomData : 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>("INDCustomData").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customData").ToLocalChecked(), CustomDataGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customDataTypeID").ToLocalChecked(), CustomDataTypeIDGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDCustomData").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDCustomData(::Windows::Media::Protection::PlayReady::INDCustomData^ 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::Media::Protection::PlayReady::INDCustomData^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDCustomData^) 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());

      INDCustomData *wrapperInstance = new INDCustomData(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::Media::Protection::PlayReady::INDCustomData^>(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::Media::Protection::PlayReady::INDCustomData^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDCustomData^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDCustomData(winRtInstance));
    }


  



    static void CustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(info.This()))
      {
        return;
      }

      INDCustomData *wrapper = INDCustomData::Unwrap<INDCustomData>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->CustomData;
        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 CustomDataTypeIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(info.This()))
      {
        return;
      }

      INDCustomData *wrapper = INDCustomData::Unwrap<INDCustomData>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->CustomDataTypeID;
        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;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDCustomData^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDCustomData(::Windows::Media::Protection::PlayReady::INDCustomData^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDCustomData^ UnwrapINDCustomData(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDCustomData::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDCustomData(::Windows::Media::Protection::PlayReady::INDCustomData^ 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>(INDCustomData::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDCustomData^ UnwrapINDCustomData(Local<Value> value)
  {
     return INDCustomData::Unwrap<INDCustomData>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDCustomData(Local<Object> exports)
  {
    INDCustomData::Init(exports);
  }

  class INDStreamParser : 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>("INDStreamParser").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "parseData", ParseData);
      Nan::SetPrototypeMethod(localRef, "getStreamInformation", GetStreamInformation);
      Nan::SetPrototypeMethod(localRef, "beginOfStream", BeginOfStream);
      Nan::SetPrototypeMethod(localRef, "endOfStream", EndOfStream);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("notifier").ToLocalChecked(), NotifierGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDStreamParser").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDStreamParser(::Windows::Media::Protection::PlayReady::INDStreamParser^ 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::Media::Protection::PlayReady::INDStreamParser^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParser^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDStreamParser^) 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());

      INDStreamParser *wrapperInstance = new INDStreamParser(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::Media::Protection::PlayReady::INDStreamParser^>(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::Media::Protection::PlayReady::INDStreamParser^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDStreamParser^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDStreamParser(winRtInstance));
    }


  
    static void ParseData(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParser^>(info.This()))
      {
        return;
      }

      INDStreamParser *wrapper = INDStreamParser::Unwrap<INDStreamParser>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          wrapper->_instance->ParseData(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 GetStreamInformation(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParser^>(info.This()))
      {
        return;
      }

      INDStreamParser *wrapper = INDStreamParser::Unwrap<INDStreamParser>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::IMediaStreamDescriptor^>(info[0]))
      {
        try
        {
          ::Windows::Media::Core::IMediaStreamDescriptor^ arg0 = dynamic_cast<::Windows::Media::Core::IMediaStreamDescriptor^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Media::Protection::PlayReady::NDMediaStreamType arg1;
          
          unsigned int result;
          result = wrapper->_instance->GetStreamInformation(arg0, &arg1);
          Local<Object> resObj = Nan::New<Object>();
          Nan::Set(resObj, Nan::New<String>("number").ToLocalChecked(), Nan::New<Integer>(result));
          Nan::Set(resObj, Nan::New<String>("streamType").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(arg1)));
          info.GetReturnValue().Set(resObj);
          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 BeginOfStream(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParser^>(info.This()))
      {
        return;
      }

      INDStreamParser *wrapper = INDStreamParser::Unwrap<INDStreamParser>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->BeginOfStream();
          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 EndOfStream(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParser^>(info.This()))
      {
        return;
      }

      INDStreamParser *wrapper = INDStreamParser::Unwrap<INDStreamParser>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->EndOfStream();
          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 NotifierGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParser^>(info.This()))
      {
        return;
      }

      INDStreamParser *wrapper = INDStreamParser::Unwrap<INDStreamParser>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ result = wrapper->_instance->Notifier;
        info.GetReturnValue().Set(WrapNDStreamParserNotifier(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDStreamParser^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDStreamParser(::Windows::Media::Protection::PlayReady::INDStreamParser^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDStreamParser^ UnwrapINDStreamParser(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDStreamParser::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDStreamParser(::Windows::Media::Protection::PlayReady::INDStreamParser^ 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>(INDStreamParser::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDStreamParser^ UnwrapINDStreamParser(Local<Value> value)
  {
     return INDStreamParser::Unwrap<INDStreamParser>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDStreamParser(Local<Object> exports)
  {
    INDStreamParser::Init(exports);
  }

  class NDStreamParserNotifier : 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>("NDStreamParserNotifier").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "onContentIDReceived", OnContentIDReceived);
      Nan::SetPrototypeMethod(localRef, "onMediaStreamDescriptorCreated", OnMediaStreamDescriptorCreated);
      Nan::SetPrototypeMethod(localRef, "onSampleParsed", OnSampleParsed);
      Nan::SetPrototypeMethod(localRef, "onBeginSetupDecryptor", OnBeginSetupDecryptor);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NDStreamParserNotifier").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NDStreamParserNotifier(::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ 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::Media::Protection::PlayReady::NDStreamParserNotifier^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::NDStreamParserNotifier();
        }
        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());

      NDStreamParserNotifier *wrapperInstance = new NDStreamParserNotifier(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::Media::Protection::PlayReady::NDStreamParserNotifier^>(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::Media::Protection::PlayReady::NDStreamParserNotifier^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNDStreamParserNotifier(winRtInstance));
    }


  
    static void OnContentIDReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      NDStreamParserNotifier *wrapper = NDStreamParserNotifier::Unwrap<NDStreamParserNotifier>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ arg0 = UnwrapINDLicenseFetchDescriptor(info[0]);
          
          wrapper->_instance->OnContentIDReceived(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 OnMediaStreamDescriptorCreated(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      NDStreamParserNotifier *wrapper = NDStreamParserNotifier::Unwrap<NDStreamParserNotifier>(info.This());

      if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^>(info[0]) || info[0]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Media::Core::AudioStreamDescriptor^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::AudioStreamDescriptor^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Media::Core::AudioStreamDescriptor^ {
                   return dynamic_cast<::Windows::Media::Core::AudioStreamDescriptor^>(NodeRT::Utils::GetObjectInstance(value));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Media::Core::VideoStreamDescriptor^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::VideoStreamDescriptor^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Media::Core::VideoStreamDescriptor^ {
                   return dynamic_cast<::Windows::Media::Core::VideoStreamDescriptor^>(NodeRT::Utils::GetObjectInstance(value));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          wrapper->_instance->OnMediaStreamDescriptorCreated(arg0, arg1);
          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 OnSampleParsed(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      NDStreamParserNotifier *wrapper = NDStreamParserNotifier::Unwrap<NDStreamParserNotifier>(info.This());

      if (info.Length() == 6
        && info[0]->IsUint32()
        && info[1]->IsInt32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::MediaStreamSample^>(info[2])
        && info[3]->IsNumber()
        && info[4]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[5]) || info[5]->IsArray()))
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          ::Windows::Media::Protection::PlayReady::NDMediaStreamType arg1 = static_cast<::Windows::Media::Protection::PlayReady::NDMediaStreamType>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          ::Windows::Media::Core::MediaStreamSample^ arg2 = dynamic_cast<::Windows::Media::Core::MediaStreamSample^>(NodeRT::Utils::GetObjectInstance(info[2]));
          __int64 arg3 = Nan::To<int64_t>(info[3]).FromMaybe(0);
          ::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat arg4 = static_cast<::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat>(Nan::To<int32_t>(info[4]).FromMaybe(0));
          ::Platform::Array<unsigned char>^ arg5 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[5]);
          
          wrapper->_instance->OnSampleParsed(arg0, arg1, arg2, arg3, arg4, arg5);
          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 OnBeginSetupDecryptor(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      NDStreamParserNotifier *wrapper = NDStreamParserNotifier::Unwrap<NDStreamParserNotifier>(info.This());

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::IMediaStreamDescriptor^>(info[0])
        && NodeRT::Utils::IsGuid(info[1])
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[2]) || info[2]->IsArray()))
      {
        try
        {
          ::Windows::Media::Core::IMediaStreamDescriptor^ arg0 = dynamic_cast<::Windows::Media::Core::IMediaStreamDescriptor^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Platform::Guid arg1 = NodeRT::Utils::GuidFromJs(info[1]);
          ::Platform::Array<unsigned char>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
          
          wrapper->_instance->OnBeginSetupDecryptor(arg0, arg1, arg2);
          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::Media::Protection::PlayReady::NDStreamParserNotifier^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNDStreamParserNotifier(::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ UnwrapNDStreamParserNotifier(Local<Value> value);
  };
  Persistent<FunctionTemplate> NDStreamParserNotifier::s_constructorTemplate;

  v8::Local<v8::Value> WrapNDStreamParserNotifier(::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ 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>(NDStreamParserNotifier::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::NDStreamParserNotifier^ UnwrapNDStreamParserNotifier(Local<Value> value)
  {
     return NDStreamParserNotifier::Unwrap<NDStreamParserNotifier>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNDStreamParserNotifier(Local<Object> exports)
  {
    NDStreamParserNotifier::Init(exports);
  }

  class INDStreamParserNotifier : 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>("INDStreamParserNotifier").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "onContentIDReceived", OnContentIDReceived);
      Nan::SetPrototypeMethod(localRef, "onMediaStreamDescriptorCreated", OnMediaStreamDescriptorCreated);
      Nan::SetPrototypeMethod(localRef, "onSampleParsed", OnSampleParsed);
      Nan::SetPrototypeMethod(localRef, "onBeginSetupDecryptor", OnBeginSetupDecryptor);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDStreamParserNotifier").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDStreamParserNotifier(::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^ 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::Media::Protection::PlayReady::INDStreamParserNotifier^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^) 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());

      INDStreamParserNotifier *wrapperInstance = new INDStreamParserNotifier(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::Media::Protection::PlayReady::INDStreamParserNotifier^>(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::Media::Protection::PlayReady::INDStreamParserNotifier^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDStreamParserNotifier(winRtInstance));
    }


  
    static void OnContentIDReceived(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      INDStreamParserNotifier *wrapper = INDStreamParserNotifier::Unwrap<INDStreamParserNotifier>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ arg0 = UnwrapINDLicenseFetchDescriptor(info[0]);
          
          wrapper->_instance->OnContentIDReceived(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 OnMediaStreamDescriptorCreated(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      INDStreamParserNotifier *wrapper = INDStreamParserNotifier::Unwrap<INDStreamParserNotifier>(info.This());

      if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^>(info[0]) || info[0]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Media::Core::AudioStreamDescriptor^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::AudioStreamDescriptor^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Media::Core::AudioStreamDescriptor^ {
                   return dynamic_cast<::Windows::Media::Core::AudioStreamDescriptor^>(NodeRT::Utils::GetObjectInstance(value));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::AudioStreamDescriptor^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Media::Core::VideoStreamDescriptor^>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::VideoStreamDescriptor^>(value);
                 },
                 [](Local<Value> value) -> ::Windows::Media::Core::VideoStreamDescriptor^ {
                   return dynamic_cast<::Windows::Media::Core::VideoStreamDescriptor^>(NodeRT::Utils::GetObjectInstance(value));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IVector<::Windows::Media::Core::VideoStreamDescriptor^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          wrapper->_instance->OnMediaStreamDescriptorCreated(arg0, arg1);
          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 OnSampleParsed(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      INDStreamParserNotifier *wrapper = INDStreamParserNotifier::Unwrap<INDStreamParserNotifier>(info.This());

      if (info.Length() == 6
        && info[0]->IsUint32()
        && info[1]->IsInt32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::MediaStreamSample^>(info[2])
        && info[3]->IsNumber()
        && info[4]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[5]) || info[5]->IsArray()))
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(Nan::To<uint32_t>(info[0]).FromMaybe(0));
          ::Windows::Media::Protection::PlayReady::NDMediaStreamType arg1 = static_cast<::Windows::Media::Protection::PlayReady::NDMediaStreamType>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          ::Windows::Media::Core::MediaStreamSample^ arg2 = dynamic_cast<::Windows::Media::Core::MediaStreamSample^>(NodeRT::Utils::GetObjectInstance(info[2]));
          __int64 arg3 = Nan::To<int64_t>(info[3]).FromMaybe(0);
          ::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat arg4 = static_cast<::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat>(Nan::To<int32_t>(info[4]).FromMaybe(0));
          ::Platform::Array<unsigned char>^ arg5 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[5]);
          
          wrapper->_instance->OnSampleParsed(arg0, arg1, arg2, arg3, arg4, arg5);
          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 OnBeginSetupDecryptor(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^>(info.This()))
      {
        return;
      }

      INDStreamParserNotifier *wrapper = INDStreamParserNotifier::Unwrap<INDStreamParserNotifier>(info.This());

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::IMediaStreamDescriptor^>(info[0])
        && NodeRT::Utils::IsGuid(info[1])
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[2]) || info[2]->IsArray()))
      {
        try
        {
          ::Windows::Media::Core::IMediaStreamDescriptor^ arg0 = dynamic_cast<::Windows::Media::Core::IMediaStreamDescriptor^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Platform::Guid arg1 = NodeRT::Utils::GuidFromJs(info[1]);
          ::Platform::Array<unsigned char>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
          
          wrapper->_instance->OnBeginSetupDecryptor(arg0, arg1, arg2);
          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::Media::Protection::PlayReady::INDStreamParserNotifier^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDStreamParserNotifier(::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^ UnwrapINDStreamParserNotifier(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDStreamParserNotifier::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDStreamParserNotifier(::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^ 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>(INDStreamParserNotifier::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDStreamParserNotifier^ UnwrapINDStreamParserNotifier(Local<Value> value)
  {
     return INDStreamParserNotifier::Unwrap<INDStreamParserNotifier>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDStreamParserNotifier(Local<Object> exports)
  {
    INDStreamParserNotifier::Init(exports);
  }

  class INDSendResult : 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>("INDSendResult").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("response").ToLocalChecked(), ResponseGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDSendResult").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDSendResult(::Windows::Media::Protection::PlayReady::INDSendResult^ 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::Media::Protection::PlayReady::INDSendResult^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDSendResult^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDSendResult^) 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());

      INDSendResult *wrapperInstance = new INDSendResult(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::Media::Protection::PlayReady::INDSendResult^>(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::Media::Protection::PlayReady::INDSendResult^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDSendResult^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDSendResult(winRtInstance));
    }


  



    static void ResponseGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDSendResult^>(info.This()))
      {
        return;
      }

      INDSendResult *wrapper = INDSendResult::Unwrap<INDSendResult>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->Response;
        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;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDSendResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDSendResult(::Windows::Media::Protection::PlayReady::INDSendResult^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDSendResult^ UnwrapINDSendResult(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDSendResult::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDSendResult(::Windows::Media::Protection::PlayReady::INDSendResult^ 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>(INDSendResult::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDSendResult^ UnwrapINDSendResult(Local<Value> value)
  {
     return INDSendResult::Unwrap<INDSendResult>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDSendResult(Local<Object> exports)
  {
    INDSendResult::Init(exports);
  }

  class INDMessenger : 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>("INDMessenger").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
                  
      Nan::SetPrototypeMethod(localRef, "sendRegistrationRequestAsync", SendRegistrationRequestAsync);
      Nan::SetPrototypeMethod(localRef, "sendProximityDetectionStartAsync", SendProximityDetectionStartAsync);
      Nan::SetPrototypeMethod(localRef, "sendProximityDetectionResponseAsync", SendProximityDetectionResponseAsync);
      Nan::SetPrototypeMethod(localRef, "sendLicenseFetchRequestAsync", SendLicenseFetchRequestAsync);
      
                  
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDMessenger").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDMessenger(::Windows::Media::Protection::PlayReady::INDMessenger^ 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::Media::Protection::PlayReady::INDMessenger^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDMessenger^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDMessenger^) 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());

      INDMessenger *wrapperInstance = new INDMessenger(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::Media::Protection::PlayReady::INDMessenger^>(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::Media::Protection::PlayReady::INDMessenger^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDMessenger^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDMessenger(winRtInstance));
    }


    static void SendRegistrationRequestAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDMessenger^>(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;
      }

      INDMessenger *wrapper = INDMessenger::Unwrap<INDMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 3
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          op = wrapper->_instance->SendRegistrationRequestAsync(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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 SendProximityDetectionStartAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDMessenger^>(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;
      }

      INDMessenger *wrapper = INDMessenger::Unwrap<INDMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 5
        && info[0]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[2]) || info[2]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[3]) || info[3]->IsArray()))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::NDProximityDetectionType arg0 = static_cast<::Windows::Media::Protection::PlayReady::NDProximityDetectionType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Platform::Array<unsigned char>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
          ::Platform::Array<unsigned char>^ arg3 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[3]);
          
          op = wrapper->_instance->SendProximityDetectionStartAsync(arg0,arg1,arg2,arg3);
        }
        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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 SendProximityDetectionResponseAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDMessenger^>(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;
      }

      INDMessenger *wrapper = INDMessenger::Unwrap<INDMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 5
        && info[0]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[2]) || info[2]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[3]) || info[3]->IsArray()))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::NDProximityDetectionType arg0 = static_cast<::Windows::Media::Protection::PlayReady::NDProximityDetectionType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Platform::Array<unsigned char>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
          ::Platform::Array<unsigned char>^ arg3 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[3]);
          
          op = wrapper->_instance->SendProximityDetectionResponseAsync(arg0,arg1,arg2,arg3);
        }
        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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 SendLicenseFetchRequestAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDMessenger^>(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;
      }

      INDMessenger *wrapper = INDMessenger::Unwrap<INDMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 3
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          op = wrapper->_instance->SendLicenseFetchRequestAsync(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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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::Media::Protection::PlayReady::INDMessenger^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDMessenger(::Windows::Media::Protection::PlayReady::INDMessenger^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDMessenger^ UnwrapINDMessenger(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDMessenger::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDMessenger(::Windows::Media::Protection::PlayReady::INDMessenger^ 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>(INDMessenger::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDMessenger^ UnwrapINDMessenger(Local<Value> value)
  {
     return INDMessenger::Unwrap<INDMessenger>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDMessenger(Local<Object> exports)
  {
    INDMessenger::Init(exports);
  }

  class NDTCPMessenger : 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>("NDTCPMessenger").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
                  
      Nan::SetPrototypeMethod(localRef, "sendRegistrationRequestAsync", SendRegistrationRequestAsync);
      Nan::SetPrototypeMethod(localRef, "sendProximityDetectionStartAsync", SendProximityDetectionStartAsync);
      Nan::SetPrototypeMethod(localRef, "sendProximityDetectionResponseAsync", SendProximityDetectionResponseAsync);
      Nan::SetPrototypeMethod(localRef, "sendLicenseFetchRequestAsync", SendLicenseFetchRequestAsync);
      
                  
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NDTCPMessenger").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NDTCPMessenger(::Windows::Media::Protection::PlayReady::NDTCPMessenger^ 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::Media::Protection::PlayReady::NDTCPMessenger^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDTCPMessenger^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::NDTCPMessenger^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && info[0]->IsString()
        && info[1]->IsUint32())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          unsigned int arg1 = static_cast<unsigned int>(Nan::To<uint32_t>(info[1]).FromMaybe(0));
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::NDTCPMessenger(arg0,arg1);
        }
        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());

      NDTCPMessenger *wrapperInstance = new NDTCPMessenger(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::Media::Protection::PlayReady::NDTCPMessenger^>(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::Media::Protection::PlayReady::NDTCPMessenger^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::NDTCPMessenger^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNDTCPMessenger(winRtInstance));
    }


    static void SendRegistrationRequestAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDTCPMessenger^>(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;
      }

      NDTCPMessenger *wrapper = NDTCPMessenger::Unwrap<NDTCPMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 3
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          op = wrapper->_instance->SendRegistrationRequestAsync(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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 SendProximityDetectionStartAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDTCPMessenger^>(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;
      }

      NDTCPMessenger *wrapper = NDTCPMessenger::Unwrap<NDTCPMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 5
        && info[0]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[2]) || info[2]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[3]) || info[3]->IsArray()))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::NDProximityDetectionType arg0 = static_cast<::Windows::Media::Protection::PlayReady::NDProximityDetectionType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Platform::Array<unsigned char>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
          ::Platform::Array<unsigned char>^ arg3 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[3]);
          
          op = wrapper->_instance->SendProximityDetectionStartAsync(arg0,arg1,arg2,arg3);
        }
        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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 SendProximityDetectionResponseAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDTCPMessenger^>(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;
      }

      NDTCPMessenger *wrapper = NDTCPMessenger::Unwrap<NDTCPMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 5
        && info[0]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[2]) || info[2]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[3]) || info[3]->IsArray()))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::NDProximityDetectionType arg0 = static_cast<::Windows::Media::Protection::PlayReady::NDProximityDetectionType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Platform::Array<unsigned char>^ arg2 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[2]);
          ::Platform::Array<unsigned char>^ arg3 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[3]);
          
          op = wrapper->_instance->SendProximityDetectionResponseAsync(arg0,arg1,arg2,arg3);
        }
        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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 SendLicenseFetchRequestAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDTCPMessenger^>(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;
      }

      NDTCPMessenger *wrapper = NDTCPMessenger::Unwrap<NDTCPMessenger>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDSendResult^>^ op;
    

      if (info.Length() == 3
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          op = wrapper->_instance->SendLicenseFetchRequestAsync(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::Media::Protection::PlayReady::INDSendResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDSendResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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::Media::Protection::PlayReady::NDTCPMessenger^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNDTCPMessenger(::Windows::Media::Protection::PlayReady::NDTCPMessenger^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::NDTCPMessenger^ UnwrapNDTCPMessenger(Local<Value> value);
  };
  Persistent<FunctionTemplate> NDTCPMessenger::s_constructorTemplate;

  v8::Local<v8::Value> WrapNDTCPMessenger(::Windows::Media::Protection::PlayReady::NDTCPMessenger^ 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>(NDTCPMessenger::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::NDTCPMessenger^ UnwrapNDTCPMessenger(Local<Value> value)
  {
     return NDTCPMessenger::Unwrap<NDTCPMessenger>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNDTCPMessenger(Local<Object> exports)
  {
    NDTCPMessenger::Init(exports);
  }

  class INDTransmitterProperties : 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>("INDTransmitterProperties").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("certificateType").ToLocalChecked(), CertificateTypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("clientID").ToLocalChecked(), ClientIDGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("expirationDate").ToLocalChecked(), ExpirationDateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("modelDigest").ToLocalChecked(), ModelDigestGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("modelManufacturerName").ToLocalChecked(), ModelManufacturerNameGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("modelName").ToLocalChecked(), ModelNameGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("modelNumber").ToLocalChecked(), ModelNumberGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("platformIdentifier").ToLocalChecked(), PlatformIdentifierGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("securityLevel").ToLocalChecked(), SecurityLevelGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("securityVersion").ToLocalChecked(), SecurityVersionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("supportedFeatures").ToLocalChecked(), SupportedFeaturesGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDTransmitterProperties").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDTransmitterProperties(::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ 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::Media::Protection::PlayReady::INDTransmitterProperties^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDTransmitterProperties^) 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());

      INDTransmitterProperties *wrapperInstance = new INDTransmitterProperties(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::Media::Protection::PlayReady::INDTransmitterProperties^>(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::Media::Protection::PlayReady::INDTransmitterProperties^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDTransmitterProperties^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDTransmitterProperties(winRtInstance));
    }


  



    static void CertificateTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::NDCertificateType result = wrapper->_instance->CertificateType;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ClientIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->ClientID;
        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 ExpirationDateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        ::Windows::Foundation::DateTime result = wrapper->_instance->ExpirationDate;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ModelDigestGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->ModelDigest;
        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 ModelManufacturerNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ModelManufacturerName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ModelNameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ModelName;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ModelNumberGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ModelNumber;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PlatformIdentifierGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::NDCertificatePlatformID result = wrapper->_instance->PlatformIdentifier;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SecurityLevelGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->SecurityLevel;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SecurityVersionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->SecurityVersion;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SupportedFeaturesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDTransmitterProperties^>(info.This()))
      {
        return;
      }

      INDTransmitterProperties *wrapper = INDTransmitterProperties::Unwrap<INDTransmitterProperties>(info.This());

      try 
      {
        ::Platform::Array<::Windows::Media::Protection::PlayReady::NDCertificateFeature>^ result = wrapper->_instance->SupportedFeatures;
        info.GetReturnValue().Set(NodeRT::Collections::ArrayWrapper<::Windows::Media::Protection::PlayReady::NDCertificateFeature>::CreateArrayWrapper(result, 
            [](::Windows::Media::Protection::PlayReady::NDCertificateFeature val) -> Local<Value> {
              return Nan::New<Integer>(static_cast<int>(val));
            },
            [](Local<Value> value) -> bool {
              return value->IsInt32();
            },
            [](Local<Value> value) -> ::Windows::Media::Protection::PlayReady::NDCertificateFeature {
              return static_cast<::Windows::Media::Protection::PlayReady::NDCertificateFeature>(Nan::To<int32_t>(value).FromMaybe(0));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDTransmitterProperties(::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ UnwrapINDTransmitterProperties(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDTransmitterProperties::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDTransmitterProperties(::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ 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>(INDTransmitterProperties::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ UnwrapINDTransmitterProperties(Local<Value> value)
  {
     return INDTransmitterProperties::Unwrap<INDTransmitterProperties>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDTransmitterProperties(Local<Object> exports)
  {
    INDTransmitterProperties::Init(exports);
  }

  class INDStartResult : 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>("INDStartResult").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("mediaStreamSource").ToLocalChecked(), MediaStreamSourceGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDStartResult").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDStartResult(::Windows::Media::Protection::PlayReady::INDStartResult^ 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::Media::Protection::PlayReady::INDStartResult^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStartResult^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDStartResult^) 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());

      INDStartResult *wrapperInstance = new INDStartResult(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::Media::Protection::PlayReady::INDStartResult^>(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::Media::Protection::PlayReady::INDStartResult^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDStartResult^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDStartResult(winRtInstance));
    }


  



    static void MediaStreamSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStartResult^>(info.This()))
      {
        return;
      }

      INDStartResult *wrapper = INDStartResult::Unwrap<INDStartResult>(info.This());

      try 
      {
        ::Windows::Media::Core::MediaStreamSource^ result = wrapper->_instance->MediaStreamSource;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Core", "MediaStreamSource", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDStartResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDStartResult(::Windows::Media::Protection::PlayReady::INDStartResult^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDStartResult^ UnwrapINDStartResult(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDStartResult::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDStartResult(::Windows::Media::Protection::PlayReady::INDStartResult^ 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>(INDStartResult::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDStartResult^ UnwrapINDStartResult(Local<Value> value)
  {
     return INDStartResult::Unwrap<INDStartResult>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDStartResult(Local<Object> exports)
  {
    INDStartResult::Init(exports);
  }

  class INDLicenseFetchResult : 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>("INDLicenseFetchResult").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDLicenseFetchResult").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDLicenseFetchResult(::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ 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::Media::Protection::PlayReady::INDLicenseFetchResult^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^) 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());

      INDLicenseFetchResult *wrapperInstance = new INDLicenseFetchResult(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::Media::Protection::PlayReady::INDLicenseFetchResult^>(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::Media::Protection::PlayReady::INDLicenseFetchResult^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDLicenseFetchResult(winRtInstance));
    }


  



    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^>(info.This()))
      {
        return;
      }

      INDLicenseFetchResult *wrapper = INDLicenseFetchResult::Unwrap<INDLicenseFetchResult>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::INDCustomData^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(WrapINDCustomData(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDLicenseFetchResult(::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ UnwrapINDLicenseFetchResult(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDLicenseFetchResult::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDLicenseFetchResult(::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ 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>(INDLicenseFetchResult::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^ UnwrapINDLicenseFetchResult(Local<Value> value)
  {
     return INDLicenseFetchResult::Unwrap<INDLicenseFetchResult>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDLicenseFetchResult(Local<Object> exports)
  {
    INDLicenseFetchResult::Init(exports);
  }

  class NDLicenseFetchDescriptor : 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>("NDLicenseFetchDescriptor").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("licenseFetchChallengeCustomData").ToLocalChecked(), LicenseFetchChallengeCustomDataGetter, LicenseFetchChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contentID").ToLocalChecked(), ContentIDGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contentIDType").ToLocalChecked(), ContentIDTypeGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NDLicenseFetchDescriptor").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ 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::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 3
        && info[0]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray())
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(info[2]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::NDContentIDType arg0 = static_cast<::Windows::Media::Protection::PlayReady::NDContentIDType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          ::Windows::Media::Protection::PlayReady::INDCustomData^ arg2 = UnwrapINDCustomData(info[2]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      NDLicenseFetchDescriptor *wrapperInstance = new NDLicenseFetchDescriptor(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::Media::Protection::PlayReady::NDLicenseFetchDescriptor^>(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::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNDLicenseFetchDescriptor(winRtInstance));
    }


  



    static void LicenseFetchChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      NDLicenseFetchDescriptor *wrapper = NDLicenseFetchDescriptor::Unwrap<NDLicenseFetchDescriptor>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::INDCustomData^ result = wrapper->_instance->LicenseFetchChallengeCustomData;
        info.GetReturnValue().Set(WrapINDCustomData(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void LicenseFetchChallengeCustomDataSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      NDLicenseFetchDescriptor *wrapper = NDLicenseFetchDescriptor::Unwrap<NDLicenseFetchDescriptor>(info.This());

      try 
      {
        
        ::Windows::Media::Protection::PlayReady::INDCustomData^ winRtValue = dynamic_cast<::Windows::Media::Protection::PlayReady::INDCustomData^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->LicenseFetchChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ContentIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      NDLicenseFetchDescriptor *wrapper = NDLicenseFetchDescriptor::Unwrap<NDLicenseFetchDescriptor>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->ContentID;
        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 ContentIDTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^>(info.This()))
      {
        return;
      }

      NDLicenseFetchDescriptor *wrapper = NDLicenseFetchDescriptor::Unwrap<NDLicenseFetchDescriptor>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::NDContentIDType result = wrapper->_instance->ContentIDType;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ UnwrapNDLicenseFetchDescriptor(Local<Value> value);
  };
  Persistent<FunctionTemplate> NDLicenseFetchDescriptor::s_constructorTemplate;

  v8::Local<v8::Value> WrapNDLicenseFetchDescriptor(::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ 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>(NDLicenseFetchDescriptor::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::NDLicenseFetchDescriptor^ UnwrapNDLicenseFetchDescriptor(Local<Value> value)
  {
     return NDLicenseFetchDescriptor::Unwrap<NDLicenseFetchDescriptor>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNDLicenseFetchDescriptor(Local<Object> exports)
  {
    NDLicenseFetchDescriptor::Init(exports);
  }

  class INDRegistrationCompletedEventArgs : 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>("INDRegistrationCompletedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("transmitterCertificateAccepted").ToLocalChecked(), TransmitterCertificateAcceptedGetter, TransmitterCertificateAcceptedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("transmitterProperties").ToLocalChecked(), TransmitterPropertiesGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDRegistrationCompletedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDRegistrationCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ 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::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^) 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());

      INDRegistrationCompletedEventArgs *wrapperInstance = new INDRegistrationCompletedEventArgs(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::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^>(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::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDRegistrationCompletedEventArgs(winRtInstance));
    }


  



    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^>(info.This()))
      {
        return;
      }

      INDRegistrationCompletedEventArgs *wrapper = INDRegistrationCompletedEventArgs::Unwrap<INDRegistrationCompletedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::INDCustomData^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(WrapINDCustomData(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TransmitterCertificateAcceptedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^>(info.This()))
      {
        return;
      }

      INDRegistrationCompletedEventArgs *wrapper = INDRegistrationCompletedEventArgs::Unwrap<INDRegistrationCompletedEventArgs>(info.This());

      try 
      {
        bool result = wrapper->_instance->TransmitterCertificateAccepted;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TransmitterCertificateAcceptedSetter(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::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^>(info.This()))
      {
        return;
      }

      INDRegistrationCompletedEventArgs *wrapper = INDRegistrationCompletedEventArgs::Unwrap<INDRegistrationCompletedEventArgs>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->TransmitterCertificateAccepted = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void TransmitterPropertiesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^>(info.This()))
      {
        return;
      }

      INDRegistrationCompletedEventArgs *wrapper = INDRegistrationCompletedEventArgs::Unwrap<INDRegistrationCompletedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::INDTransmitterProperties^ result = wrapper->_instance->TransmitterProperties;
        info.GetReturnValue().Set(WrapINDTransmitterProperties(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDRegistrationCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ UnwrapINDRegistrationCompletedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDRegistrationCompletedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDRegistrationCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ 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>(INDRegistrationCompletedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ UnwrapINDRegistrationCompletedEventArgs(Local<Value> value)
  {
     return INDRegistrationCompletedEventArgs::Unwrap<INDRegistrationCompletedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDRegistrationCompletedEventArgs(Local<Object> exports)
  {
    INDRegistrationCompletedEventArgs::Init(exports);
  }

  class NDCustomData : 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>("NDCustomData").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customData").ToLocalChecked(), CustomDataGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customDataTypeID").ToLocalChecked(), CustomDataTypeIDGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NDCustomData").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NDCustomData(::Windows::Media::Protection::PlayReady::NDCustomData^ 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::Media::Protection::PlayReady::NDCustomData^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDCustomData^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::NDCustomData^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[1]) || info[1]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          ::Platform::Array<unsigned char>^ arg1 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[1]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::NDCustomData(arg0,arg1);
        }
        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());

      NDCustomData *wrapperInstance = new NDCustomData(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::Media::Protection::PlayReady::NDCustomData^>(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::Media::Protection::PlayReady::NDCustomData^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::NDCustomData^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNDCustomData(winRtInstance));
    }


  



    static void CustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDCustomData^>(info.This()))
      {
        return;
      }

      NDCustomData *wrapper = NDCustomData::Unwrap<NDCustomData>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->CustomData;
        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 CustomDataTypeIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDCustomData^>(info.This()))
      {
        return;
      }

      NDCustomData *wrapper = NDCustomData::Unwrap<NDCustomData>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->CustomDataTypeID;
        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;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::NDCustomData^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNDCustomData(::Windows::Media::Protection::PlayReady::NDCustomData^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::NDCustomData^ UnwrapNDCustomData(Local<Value> value);
  };
  Persistent<FunctionTemplate> NDCustomData::s_constructorTemplate;

  v8::Local<v8::Value> WrapNDCustomData(::Windows::Media::Protection::PlayReady::NDCustomData^ 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>(NDCustomData::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::NDCustomData^ UnwrapNDCustomData(Local<Value> value)
  {
     return NDCustomData::Unwrap<NDCustomData>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNDCustomData(Local<Object> exports)
  {
    NDCustomData::Init(exports);
  }

  class INDProximityDetectionCompletedEventArgs : 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>("INDProximityDetectionCompletedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("proximityDetectionRetryCount").ToLocalChecked(), ProximityDetectionRetryCountGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDProximityDetectionCompletedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDProximityDetectionCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ 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::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^) 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());

      INDProximityDetectionCompletedEventArgs *wrapperInstance = new INDProximityDetectionCompletedEventArgs(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::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^>(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::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDProximityDetectionCompletedEventArgs(winRtInstance));
    }


  



    static void ProximityDetectionRetryCountGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^>(info.This()))
      {
        return;
      }

      INDProximityDetectionCompletedEventArgs *wrapper = INDProximityDetectionCompletedEventArgs::Unwrap<INDProximityDetectionCompletedEventArgs>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ProximityDetectionRetryCount;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDProximityDetectionCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ UnwrapINDProximityDetectionCompletedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDProximityDetectionCompletedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDProximityDetectionCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ 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>(INDProximityDetectionCompletedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ UnwrapINDProximityDetectionCompletedEventArgs(Local<Value> value)
  {
     return INDProximityDetectionCompletedEventArgs::Unwrap<INDProximityDetectionCompletedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDProximityDetectionCompletedEventArgs(Local<Object> exports)
  {
    INDProximityDetectionCompletedEventArgs::Init(exports);
  }

  class INDLicenseFetchCompletedEventArgs : 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>("INDLicenseFetchCompletedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDLicenseFetchCompletedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDLicenseFetchCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ 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::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^) 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());

      INDLicenseFetchCompletedEventArgs *wrapperInstance = new INDLicenseFetchCompletedEventArgs(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::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^>(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::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDLicenseFetchCompletedEventArgs(winRtInstance));
    }


  



    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^>(info.This()))
      {
        return;
      }

      INDLicenseFetchCompletedEventArgs *wrapper = INDLicenseFetchCompletedEventArgs::Unwrap<INDLicenseFetchCompletedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::INDCustomData^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(WrapINDCustomData(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDLicenseFetchCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ UnwrapINDLicenseFetchCompletedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDLicenseFetchCompletedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDLicenseFetchCompletedEventArgs(::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ 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>(INDLicenseFetchCompletedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ UnwrapINDLicenseFetchCompletedEventArgs(Local<Value> value)
  {
     return INDLicenseFetchCompletedEventArgs::Unwrap<INDLicenseFetchCompletedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDLicenseFetchCompletedEventArgs(Local<Object> exports)
  {
    INDLicenseFetchCompletedEventArgs::Init(exports);
  }

  class NDClient : 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>("NDClient").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "close", Close);
      
            
      Nan::SetPrototypeMethod(localRef, "startAsync", StartAsync);
      Nan::SetPrototypeMethod(localRef, "licenseFetchAsync", LicenseFetchAsync);
      Nan::SetPrototypeMethod(localRef, "reRegistrationAsync", ReRegistrationAsync);
      
            
      Nan::SetPrototypeMethod(localRef,"addListener", AddListener);
      Nan::SetPrototypeMethod(localRef,"on", AddListener);
      Nan::SetPrototypeMethod(localRef,"removeListener", RemoveListener);
      Nan::SetPrototypeMethod(localRef, "off", RemoveListener);
            
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NDClient").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NDClient(::Windows::Media::Protection::PlayReady::NDClient^ 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::Media::Protection::PlayReady::NDClient^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::NDClient^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDDownloadEngine^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStreamParser^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDMessenger^>(info[2]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::INDDownloadEngine^ arg0 = UnwrapINDDownloadEngine(info[0]);
          ::Windows::Media::Protection::PlayReady::INDStreamParser^ arg1 = UnwrapINDStreamParser(info[1]);
          ::Windows::Media::Protection::PlayReady::INDMessenger^ arg2 = UnwrapINDMessenger(info[2]);
          
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::NDClient(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
	    	return;
      }

      NodeRT::Utils::SetHiddenValue(info.This(), Nan::New<String>("__winRtInstance__").ToLocalChecked(), True());

      NDClient *wrapperInstance = new NDClient(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::Media::Protection::PlayReady::NDClient^>(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::Media::Protection::PlayReady::NDClient^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::NDClient^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNDClient(winRtInstance));
    }


    static void StartAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(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;
      }

      NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDStartResult^>^ op;
    

      if (info.Length() == 5
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(info[0])
        && info[1]->IsUint32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(info[2])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info[3]))
      {
        try
        {
          ::Windows::Foundation::Uri^ arg0 = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(info[0]));
          unsigned int arg1 = static_cast<unsigned int>(Nan::To<uint32_t>(info[1]).FromMaybe(0));
          ::Windows::Media::Protection::PlayReady::INDCustomData^ arg2 = UnwrapINDCustomData(info[2]);
          ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ arg3 = UnwrapINDLicenseFetchDescriptor(info[3]);
          
          op = wrapper->_instance->StartAsync(arg0,arg1,arg2,arg3);
        }
        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::Media::Protection::PlayReady::INDStartResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDStartResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 LicenseFetchAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(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;
      }

      NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Protection::PlayReady::INDLicenseFetchResult^>^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::INDLicenseFetchDescriptor^ arg0 = UnwrapINDLicenseFetchDescriptor(info[0]);
          
          op = wrapper->_instance->LicenseFetchAsync(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::Media::Protection::PlayReady::INDLicenseFetchResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapINDLicenseFetchResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            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 ReRegistrationAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(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;
      }

      NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDCustomData^>(info[0]))
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::INDCustomData^ arg0 = UnwrapINDCustomData(info[0]);
          
          op = wrapper->_instance->ReRegistrationAsync(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<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 Close(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
      {
        return;
      }

      NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          wrapper->_instance->Close();
          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 AddListener(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() < 2 || !info[0]->IsString() || !info[1]->IsFunction())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"wrong arguments, expected arguments are eventName(string),callback(function)")));
		return;
      }

      String::Value eventName(info[0]);
      auto str = *eventName;
      
      Local<Function> callback = info[1].As<Function>();
      
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      if (NodeRT::Utils::CaseInsenstiveEquals(L"closedCaptionDataReceived", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
        {
          Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
		  return;
        }
        NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
      
        try
        {
          Persistent<Object>* perstPtr = new Persistent<Object>();
          perstPtr->Reset(NodeRT::Utils::CreateCallbackObjectInDomain(callback));
          std::shared_ptr<Persistent<Object>> callbackObjPtr(perstPtr, 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Reset();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->ClosedCaptionDataReceived::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Protection::PlayReady::NDClient^, ::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Protection::PlayReady::NDClient^ arg0, ::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapNDClient(arg0);
                Local<Value> wrappedArg1 = WrapINDClosedCaptionDataReceivedEventArgs(arg1);

                if (tryCatch.HasCaught())
                {
                  error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
                }
                else 
                {
                  error = Undefined();
                }

				// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
				// can be fixed by wrapping the conversion code in a function and calling it on the fly
				// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
				tryCatch.~TryCatch();


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Local<Value> args[] = { wrappedArg0, wrappedArg1 };
                Local<Object> callbackObjLocalRef = Nan::New<Object>(*callbackObjPtr);
                NodeRT::Utils::CallCallbackInDomain(callbackObjLocalRef, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"licenseFetchCompleted", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
        {
          Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
		  return;
        }
        NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
      
        try
        {
          Persistent<Object>* perstPtr = new Persistent<Object>();
          perstPtr->Reset(NodeRT::Utils::CreateCallbackObjectInDomain(callback));
          std::shared_ptr<Persistent<Object>> callbackObjPtr(perstPtr, 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Reset();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->LicenseFetchCompleted::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Protection::PlayReady::NDClient^, ::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Protection::PlayReady::NDClient^ arg0, ::Windows::Media::Protection::PlayReady::INDLicenseFetchCompletedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapNDClient(arg0);
                Local<Value> wrappedArg1 = WrapINDLicenseFetchCompletedEventArgs(arg1);

                if (tryCatch.HasCaught())
                {
                  error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
                }
                else 
                {
                  error = Undefined();
                }

				// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
				// can be fixed by wrapping the conversion code in a function and calling it on the fly
				// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
				tryCatch.~TryCatch();


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Local<Value> args[] = { wrappedArg0, wrappedArg1 };
                Local<Object> callbackObjLocalRef = Nan::New<Object>(*callbackObjPtr);
                NodeRT::Utils::CallCallbackInDomain(callbackObjLocalRef, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"proximityDetectionCompleted", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
        {
          Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
		  return;
        }
        NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
      
        try
        {
          Persistent<Object>* perstPtr = new Persistent<Object>();
          perstPtr->Reset(NodeRT::Utils::CreateCallbackObjectInDomain(callback));
          std::shared_ptr<Persistent<Object>> callbackObjPtr(perstPtr, 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Reset();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->ProximityDetectionCompleted::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Protection::PlayReady::NDClient^, ::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Protection::PlayReady::NDClient^ arg0, ::Windows::Media::Protection::PlayReady::INDProximityDetectionCompletedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapNDClient(arg0);
                Local<Value> wrappedArg1 = WrapINDProximityDetectionCompletedEventArgs(arg1);

                if (tryCatch.HasCaught())
                {
                  error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
                }
                else 
                {
                  error = Undefined();
                }

				// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
				// can be fixed by wrapping the conversion code in a function and calling it on the fly
				// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
				tryCatch.~TryCatch();


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Local<Value> args[] = { wrappedArg0, wrappedArg1 };
                Local<Object> callbackObjLocalRef = Nan::New<Object>(*callbackObjPtr);
                NodeRT::Utils::CallCallbackInDomain(callbackObjLocalRef, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"reRegistrationNeeded", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
        {
          Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
		  return;
        }
        NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
      
        try
        {
          Persistent<Object>* perstPtr = new Persistent<Object>();
          perstPtr->Reset(NodeRT::Utils::CreateCallbackObjectInDomain(callback));
          std::shared_ptr<Persistent<Object>> callbackObjPtr(perstPtr, 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Reset();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->ReRegistrationNeeded::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Protection::PlayReady::NDClient^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Media::Protection::PlayReady::NDClient^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapNDClient(arg0);
                Local<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
                }
                else 
                {
                  error = Undefined();
                }

				// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
				// can be fixed by wrapping the conversion code in a function and calling it on the fly
				// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
				tryCatch.~TryCatch();


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Local<Value> args[] = { wrappedArg0, wrappedArg1 };
                Local<Object> callbackObjLocalRef = Nan::New<Object>(*callbackObjPtr);
                NodeRT::Utils::CallCallbackInDomain(callbackObjLocalRef, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"registrationCompleted", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
        {
          Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
		  return;
        }
        NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
      
        try
        {
          Persistent<Object>* perstPtr = new Persistent<Object>();
          perstPtr->Reset(NodeRT::Utils::CreateCallbackObjectInDomain(callback));
          std::shared_ptr<Persistent<Object>> callbackObjPtr(perstPtr, 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Reset();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->RegistrationCompleted::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Protection::PlayReady::NDClient^, ::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Protection::PlayReady::NDClient^ arg0, ::Windows::Media::Protection::PlayReady::INDRegistrationCompletedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapNDClient(arg0);
                Local<Value> wrappedArg1 = WrapINDRegistrationCompletedEventArgs(arg1);

                if (tryCatch.HasCaught())
                {
                  error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
                }
                else 
                {
                  error = Undefined();
                }

				// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
				// can be fixed by wrapping the conversion code in a function and calling it on the fly
				// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
				tryCatch.~TryCatch();


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Local<Value> args[] = { wrappedArg0, wrappedArg1 };
                Local<Object> callbackObjLocalRef = Nan::New<Object>(*callbackObjPtr);
                NodeRT::Utils::CallCallbackInDomain(callbackObjLocalRef, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }

      }
      else 
      {
        Nan::ThrowError(Nan::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), info[0].As<String>())));
		return;
      }

      Local<Value> tokenMapVal = NodeRT::Utils::GetHiddenValue(callback, Nan::New<String>(REGISTRATION_TOKEN_MAP_PROPERTY_NAME).ToLocalChecked());
      Local<Object> tokenMap;

      if (tokenMapVal.IsEmpty() || Nan::Equals(tokenMapVal, Undefined()).FromMaybe(false))
      {
        tokenMap = Nan::New<Object>();
        NodeRT::Utils::SetHiddenValueWithObject(callback, Nan::New<String>(REGISTRATION_TOKEN_MAP_PROPERTY_NAME).ToLocalChecked(), tokenMap);
      }
      else
      {
        tokenMap = Nan::To<Object>(tokenMapVal).ToLocalChecked();
      }

      Nan::Set(tokenMap, info[0], CreateOpaqueWrapper(::Windows::Foundation::PropertyValue::CreateInt64(registrationToken.Value)));
    }

    static void RemoveListener(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() < 2 || !info[0]->IsString() || !info[1]->IsFunction())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"wrong arguments, expected a string and a callback")));
        return;
      }

      String::Value eventName(info[0]);
      auto str = *eventName;

      if ((NodeRT::Utils::CaseInsenstiveEquals(L"closedCaptionDataReceived", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"licenseFetchCompleted", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"proximityDetectionCompleted", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"reRegistrationNeeded", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"registrationCompleted", str)))
      {
        Nan::ThrowError(Nan::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), info[0].As<String>())));
        return;
      }

      Local<Function> callback = info[1].As<Function>();
      Local<Value> tokenMap = NodeRT::Utils::GetHiddenValue(callback, Nan::New<String>(REGISTRATION_TOKEN_MAP_PROPERTY_NAME).ToLocalChecked());
                
      if (tokenMap.IsEmpty() || Nan::Equals(tokenMap, Undefined()).FromMaybe(false))
      {
        return;
      }

      Local<Value> opaqueWrapperObj =  Nan::Get(Nan::To<Object>(tokenMap).ToLocalChecked(), info[0]).ToLocalChecked();

      if (opaqueWrapperObj.IsEmpty() || Nan::Equals(opaqueWrapperObj,Undefined()).FromMaybe(false))
      {
        return;
      }

      OpaqueWrapper *opaqueWrapper = OpaqueWrapper::Unwrap<OpaqueWrapper>(opaqueWrapperObj.As<Object>());
            
      long long tokenValue = (long long) opaqueWrapper->GetObjectInstance();
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      registrationToken.Value = tokenValue;
        
      try 
      {
        if (NodeRT::Utils::CaseInsenstiveEquals(L"closedCaptionDataReceived", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
          {
            Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return;
          }
          NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
          wrapper->_instance->ClosedCaptionDataReceived::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"licenseFetchCompleted", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
          {
            Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return;
          }
          NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
          wrapper->_instance->LicenseFetchCompleted::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"proximityDetectionCompleted", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
          {
            Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return;
          }
          NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
          wrapper->_instance->ProximityDetectionCompleted::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"reRegistrationNeeded", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
          {
            Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return;
          }
          NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
          wrapper->_instance->ReRegistrationNeeded::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"registrationCompleted", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDClient^>(info.This()))
          {
            Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return;
          }
          NDClient *wrapper = NDClient::Unwrap<NDClient>(info.This());
          wrapper->_instance->RegistrationCompleted::remove(registrationToken);
        }
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }

      Nan::Delete(Nan::To<Object>(tokenMap).ToLocalChecked(), Nan::To<String>(info[0]).ToLocalChecked());
    }
  private:
    ::Windows::Media::Protection::PlayReady::NDClient^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNDClient(::Windows::Media::Protection::PlayReady::NDClient^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::NDClient^ UnwrapNDClient(Local<Value> value);
  };
  Persistent<FunctionTemplate> NDClient::s_constructorTemplate;

  v8::Local<v8::Value> WrapNDClient(::Windows::Media::Protection::PlayReady::NDClient^ 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>(NDClient::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::NDClient^ UnwrapNDClient(Local<Value> value)
  {
     return NDClient::Unwrap<NDClient>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNDClient(Local<Object> exports)
  {
    NDClient::Init(exports);
  }

  class INDClosedCaptionDataReceivedEventArgs : 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>("INDClosedCaptionDataReceivedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("closedCaptionData").ToLocalChecked(), ClosedCaptionDataGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("closedCaptionDataFormat").ToLocalChecked(), ClosedCaptionDataFormatGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("presentationTimestamp").ToLocalChecked(), PresentationTimestampGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDClosedCaptionDataReceivedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDClosedCaptionDataReceivedEventArgs(::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ 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::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^) 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());

      INDClosedCaptionDataReceivedEventArgs *wrapperInstance = new INDClosedCaptionDataReceivedEventArgs(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::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^>(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::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDClosedCaptionDataReceivedEventArgs(winRtInstance));
    }


  



    static void ClosedCaptionDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^>(info.This()))
      {
        return;
      }

      INDClosedCaptionDataReceivedEventArgs *wrapper = INDClosedCaptionDataReceivedEventArgs::Unwrap<INDClosedCaptionDataReceivedEventArgs>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->ClosedCaptionData;
        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 ClosedCaptionDataFormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^>(info.This()))
      {
        return;
      }

      INDClosedCaptionDataReceivedEventArgs *wrapper = INDClosedCaptionDataReceivedEventArgs::Unwrap<INDClosedCaptionDataReceivedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::NDClosedCaptionFormat result = wrapper->_instance->ClosedCaptionDataFormat;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PresentationTimestampGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^>(info.This()))
      {
        return;
      }

      INDClosedCaptionDataReceivedEventArgs *wrapper = INDClosedCaptionDataReceivedEventArgs::Unwrap<INDClosedCaptionDataReceivedEventArgs>(info.This());

      try 
      {
        __int64 result = wrapper->_instance->PresentationTimestamp;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDClosedCaptionDataReceivedEventArgs(::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ UnwrapINDClosedCaptionDataReceivedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDClosedCaptionDataReceivedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDClosedCaptionDataReceivedEventArgs(::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ 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>(INDClosedCaptionDataReceivedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDClosedCaptionDataReceivedEventArgs^ UnwrapINDClosedCaptionDataReceivedEventArgs(Local<Value> value)
  {
     return INDClosedCaptionDataReceivedEventArgs::Unwrap<INDClosedCaptionDataReceivedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDClosedCaptionDataReceivedEventArgs(Local<Object> exports)
  {
    INDClosedCaptionDataReceivedEventArgs::Init(exports);
  }

  class INDStorageFileHelper : 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>("INDStorageFileHelper").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "getFileURLs", GetFileURLs);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("INDStorageFileHelper").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    INDStorageFileHelper(::Windows::Media::Protection::PlayReady::INDStorageFileHelper^ 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::Media::Protection::PlayReady::INDStorageFileHelper^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStorageFileHelper^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::INDStorageFileHelper^) 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());

      INDStorageFileHelper *wrapperInstance = new INDStorageFileHelper(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::Media::Protection::PlayReady::INDStorageFileHelper^>(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::Media::Protection::PlayReady::INDStorageFileHelper^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::INDStorageFileHelper^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapINDStorageFileHelper(winRtInstance));
    }


  
    static void GetFileURLs(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::INDStorageFileHelper^>(info.This()))
      {
        return;
      }

      INDStorageFileHelper *wrapper = INDStorageFileHelper::Unwrap<INDStorageFileHelper>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::IStorageFile^>(info[0]))
      {
        try
        {
          ::Windows::Storage::IStorageFile^ arg0 = dynamic_cast<::Windows::Storage::IStorageFile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Foundation::Collections::IVector<::Platform::String^>^ result;
          result = wrapper->_instance->GetFileURLs(arg0);
          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(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::Media::Protection::PlayReady::INDStorageFileHelper^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapINDStorageFileHelper(::Windows::Media::Protection::PlayReady::INDStorageFileHelper^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::INDStorageFileHelper^ UnwrapINDStorageFileHelper(Local<Value> value);
  };
  Persistent<FunctionTemplate> INDStorageFileHelper::s_constructorTemplate;

  v8::Local<v8::Value> WrapINDStorageFileHelper(::Windows::Media::Protection::PlayReady::INDStorageFileHelper^ 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>(INDStorageFileHelper::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::INDStorageFileHelper^ UnwrapINDStorageFileHelper(Local<Value> value)
  {
     return INDStorageFileHelper::Unwrap<INDStorageFileHelper>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitINDStorageFileHelper(Local<Object> exports)
  {
    INDStorageFileHelper::Init(exports);
  }

  class NDStorageFileHelper : 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>("NDStorageFileHelper").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "getFileURLs", GetFileURLs);
      
                        
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("NDStorageFileHelper").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    NDStorageFileHelper(::Windows::Media::Protection::PlayReady::NDStorageFileHelper^ 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::Media::Protection::PlayReady::NDStorageFileHelper^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDStorageFileHelper^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::NDStorageFileHelper^) NodeRT::Utils::GetObjectInstance(info[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Media::Protection::PlayReady::NDStorageFileHelper();
        }
        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());

      NDStorageFileHelper *wrapperInstance = new NDStorageFileHelper(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::Media::Protection::PlayReady::NDStorageFileHelper^>(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::Media::Protection::PlayReady::NDStorageFileHelper^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::NDStorageFileHelper^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapNDStorageFileHelper(winRtInstance));
    }


  
    static void GetFileURLs(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::NDStorageFileHelper^>(info.This()))
      {
        return;
      }

      NDStorageFileHelper *wrapper = NDStorageFileHelper::Unwrap<NDStorageFileHelper>(info.This());

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::IStorageFile^>(info[0]))
      {
        try
        {
          ::Windows::Storage::IStorageFile^ arg0 = dynamic_cast<::Windows::Storage::IStorageFile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          ::Windows::Foundation::Collections::IVector<::Platform::String^>^ result;
          result = wrapper->_instance->GetFileURLs(arg0);
          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(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::Media::Protection::PlayReady::NDStorageFileHelper^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapNDStorageFileHelper(::Windows::Media::Protection::PlayReady::NDStorageFileHelper^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::NDStorageFileHelper^ UnwrapNDStorageFileHelper(Local<Value> value);
  };
  Persistent<FunctionTemplate> NDStorageFileHelper::s_constructorTemplate;

  v8::Local<v8::Value> WrapNDStorageFileHelper(::Windows::Media::Protection::PlayReady::NDStorageFileHelper^ 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>(NDStorageFileHelper::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::NDStorageFileHelper^ UnwrapNDStorageFileHelper(Local<Value> value)
  {
     return NDStorageFileHelper::Unwrap<NDStorageFileHelper>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitNDStorageFileHelper(Local<Object> exports)
  {
    NDStorageFileHelper::Init(exports);
  }

  class IPlayReadyServiceRequest : 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>("IPlayReadyServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "nextServiceRequest", NextServiceRequest);
      Nan::SetPrototypeMethod(localRef, "generateManualEnablingChallenge", GenerateManualEnablingChallenge);
      Nan::SetPrototypeMethod(localRef, "processManualEnablingResponse", ProcessManualEnablingResponse);
      
            
      Nan::SetPrototypeMethod(localRef, "beginServiceRequest", BeginServiceRequest);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("challengeCustomData").ToLocalChecked(), ChallengeCustomDataGetter, ChallengeCustomDataSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("responseCustomData").ToLocalChecked(), ResponseCustomDataGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("uri").ToLocalChecked(), UriGetter, UriSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IPlayReadyServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IPlayReadyServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ 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::Media::Protection::PlayReady::IPlayReadyServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^) 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());

      IPlayReadyServiceRequest *wrapperInstance = new IPlayReadyServiceRequest(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::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(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::Media::Protection::PlayReady::IPlayReadyServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(winRtInstance));
    }


    static void BeginServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(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;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->BeginServiceRequest();
        }
        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 NextServiceRequest(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ result;
          result = wrapper->_instance->NextServiceRequest();
          info.GetReturnValue().Set(WrapIPlayReadyServiceRequest(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 GenerateManualEnablingChallenge(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Protection::PlayReady::PlayReadySoapMessage^ result;
          result = wrapper->_instance->GenerateManualEnablingChallenge();
          info.GetReturnValue().Set(WrapPlayReadySoapMessage(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 ProcessManualEnablingResponse(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      if (info.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<unsigned char>^>(info[0]) || info[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<unsigned char>^ arg0 = 
            [] (v8::Local<v8::Value> value) -> ::Platform::Array<unsigned char>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<unsigned char>(value.As<Array>(), 
                 [](Local<Value> value) -> bool {
                   return value->IsInt32();
                 },
                 [](Local<Value> value) -> unsigned char {
                   return static_cast<unsigned char>(Nan::To<int32_t>(value).FromMaybe(0));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<unsigned char>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (info[0]);
          
          ::Windows::Foundation::HResult result;
          result = wrapper->_instance->ProcessManualEnablingResponse(arg0);
          info.GetReturnValue().Set(Nan::New<Integer>(result.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;
      }
    }



    static void ChallengeCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ChallengeCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ChallengeCustomDataSetter(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::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ChallengeCustomData = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ResponseCustomDataGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ResponseCustomData;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::Uri^ result = wrapper->_instance->Uri;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Foundation", "Uri", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UriSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Uri^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyServiceRequest *wrapper = IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Foundation::Uri^ winRtValue = dynamic_cast<::Windows::Foundation::Uri^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Uri = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIPlayReadyServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ UnwrapIPlayReadyServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> IPlayReadyServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapIPlayReadyServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ 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>(IPlayReadyServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::IPlayReadyServiceRequest^ UnwrapIPlayReadyServiceRequest(Local<Value> value)
  {
     return IPlayReadyServiceRequest::Unwrap<IPlayReadyServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIPlayReadyServiceRequest(Local<Object> exports)
  {
    IPlayReadyServiceRequest::Init(exports);
  }

  class IPlayReadyLicenseAcquisitionServiceRequest : 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>("IPlayReadyLicenseAcquisitionServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contentHeader").ToLocalChecked(), ContentHeaderGetter, ContentHeaderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("domainServiceId").ToLocalChecked(), DomainServiceIdGetter, DomainServiceIdSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IPlayReadyLicenseAcquisitionServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IPlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ 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::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^) 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());

      IPlayReadyLicenseAcquisitionServiceRequest *wrapperInstance = new IPlayReadyLicenseAcquisitionServiceRequest(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::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^>(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::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIPlayReadyLicenseAcquisitionServiceRequest(winRtInstance));
    }


  



    static void ContentHeaderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyLicenseAcquisitionServiceRequest *wrapper = IPlayReadyLicenseAcquisitionServiceRequest::Unwrap<IPlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ result = wrapper->_instance->ContentHeader;
        info.GetReturnValue().Set(WrapPlayReadyContentHeader(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ContentHeaderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyLicenseAcquisitionServiceRequest *wrapper = IPlayReadyLicenseAcquisitionServiceRequest::Unwrap<IPlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        
        ::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^ winRtValue = dynamic_cast<::Windows::Media::Protection::PlayReady::PlayReadyContentHeader^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->ContentHeader = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DomainServiceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyLicenseAcquisitionServiceRequest *wrapper = IPlayReadyLicenseAcquisitionServiceRequest::Unwrap<IPlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->DomainServiceId;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DomainServiceIdSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsGuid(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadyLicenseAcquisitionServiceRequest *wrapper = IPlayReadyLicenseAcquisitionServiceRequest::Unwrap<IPlayReadyLicenseAcquisitionServiceRequest>(info.This());

      try 
      {
        
        ::Platform::Guid winRtValue = NodeRT::Utils::GuidFromJs(value);

        wrapper->_instance->DomainServiceId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIPlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ UnwrapIPlayReadyLicenseAcquisitionServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> IPlayReadyLicenseAcquisitionServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapIPlayReadyLicenseAcquisitionServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ 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>(IPlayReadyLicenseAcquisitionServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::IPlayReadyLicenseAcquisitionServiceRequest^ UnwrapIPlayReadyLicenseAcquisitionServiceRequest(Local<Value> value)
  {
     return IPlayReadyLicenseAcquisitionServiceRequest::Unwrap<IPlayReadyLicenseAcquisitionServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIPlayReadyLicenseAcquisitionServiceRequest(Local<Object> exports)
  {
    IPlayReadyLicenseAcquisitionServiceRequest::Init(exports);
  }

  class IPlayReadySecureStopServiceRequest : 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>("IPlayReadySecureStopServiceRequest").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("publisherCertificate").ToLocalChecked(), PublisherCertificateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("sessionID").ToLocalChecked(), SessionIDGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("startTime").ToLocalChecked(), StartTimeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("stopped").ToLocalChecked(), StoppedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("updateTime").ToLocalChecked(), UpdateTimeGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IPlayReadySecureStopServiceRequest").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IPlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ 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::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^) 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());

      IPlayReadySecureStopServiceRequest *wrapperInstance = new IPlayReadySecureStopServiceRequest(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::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>(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::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIPlayReadySecureStopServiceRequest(winRtInstance));
    }


  



    static void PublisherCertificateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadySecureStopServiceRequest *wrapper = IPlayReadySecureStopServiceRequest::Unwrap<IPlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Platform::Array<unsigned char>^ result = wrapper->_instance->PublisherCertificate;
        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 SessionIDGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadySecureStopServiceRequest *wrapper = IPlayReadySecureStopServiceRequest::Unwrap<IPlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Platform::Guid result = wrapper->_instance->SessionID;
        info.GetReturnValue().Set(NodeRT::Utils::GuidToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void StartTimeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadySecureStopServiceRequest *wrapper = IPlayReadySecureStopServiceRequest::Unwrap<IPlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::DateTime result = wrapper->_instance->StartTime;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void StoppedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadySecureStopServiceRequest *wrapper = IPlayReadySecureStopServiceRequest::Unwrap<IPlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        bool result = wrapper->_instance->Stopped;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void UpdateTimeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^>(info.This()))
      {
        return;
      }

      IPlayReadySecureStopServiceRequest *wrapper = IPlayReadySecureStopServiceRequest::Unwrap<IPlayReadySecureStopServiceRequest>(info.This());

      try 
      {
        ::Windows::Foundation::DateTime result = wrapper->_instance->UpdateTime;
        info.GetReturnValue().Set(NodeRT::Utils::DateTimeToJS(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIPlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ wintRtInstance);
    friend ::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ UnwrapIPlayReadySecureStopServiceRequest(Local<Value> value);
  };
  Persistent<FunctionTemplate> IPlayReadySecureStopServiceRequest::s_constructorTemplate;

  v8::Local<v8::Value> WrapIPlayReadySecureStopServiceRequest(::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ 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>(IPlayReadySecureStopServiceRequest::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Protection::PlayReady::IPlayReadySecureStopServiceRequest^ UnwrapIPlayReadySecureStopServiceRequest(Local<Value> value)
  {
     return IPlayReadySecureStopServiceRequest::Unwrap<IPlayReadySecureStopServiceRequest>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIPlayReadySecureStopServiceRequest(Local<Object> exports)
  {
    IPlayReadySecureStopServiceRequest::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::Media::Protection::PlayReady::InitPlayReadyDecryptorSetupEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyEncryptionAlgorithmEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyHardwareDRMFeaturesEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyITADataFormatEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDCertificateTypeEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDCertificatePlatformIDEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDCertificateFeatureEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDProximityDetectionTypeEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDMediaStreamTypeEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDContentIDTypeEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDClosedCaptionFormatEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDStartAsyncOptionsEnum(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyContentHeader(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadySoapMessage(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyContentResolver(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyIndividualizationServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyDomainJoinServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyDomainLeaveServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyLicenseAcquisitionServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyMeteringReportServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyRevocationServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyLicenseManagement(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitIPlayReadyLicense(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyLicense(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyLicenseIterable(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyLicenseIterator(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitIPlayReadyDomain(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyDomain(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyDomainIterable(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyDomainIterator(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyStatics(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadySecureStopServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadySecureStopIterable(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadySecureStopIterator(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyITADataGenerator(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitIPlayReadyLicenseSession(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitPlayReadyLicenseSession(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDDownloadEngine(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDDownloadEngineNotifier(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDDownloadEngineNotifier(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDLicenseFetchDescriptor(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDCustomData(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDStreamParser(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDStreamParserNotifier(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDStreamParserNotifier(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDSendResult(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDMessenger(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDTCPMessenger(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDTransmitterProperties(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDStartResult(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDLicenseFetchResult(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDLicenseFetchDescriptor(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDRegistrationCompletedEventArgs(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDCustomData(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDProximityDetectionCompletedEventArgs(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDLicenseFetchCompletedEventArgs(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDClient(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDClosedCaptionDataReceivedEventArgs(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitINDStorageFileHelper(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitNDStorageFileHelper(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitIPlayReadyServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitIPlayReadyLicenseAcquisitionServiceRequest(target);
  NodeRT::Windows::Media::Protection::PlayReady::InitIPlayReadySecureStopServiceRequest(target);

  NodeRT::Utils::RegisterNameSpace("Windows.Media.Protection.PlayReady", target);
}


NODE_MODULE(binding, init)