// 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 Capture { 

  v8::Local<v8::Value> WrapCameraCaptureUIPhotoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ wintRtInstance);
  ::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ UnwrapCameraCaptureUIPhotoCaptureSettings(Local<Value> value);
  
  v8::Local<v8::Value> WrapCameraCaptureUIVideoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ wintRtInstance);
  ::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ UnwrapCameraCaptureUIVideoCaptureSettings(Local<Value> value);
  
  v8::Local<v8::Value> WrapCameraCaptureUI(::Windows::Media::Capture::CameraCaptureUI^ wintRtInstance);
  ::Windows::Media::Capture::CameraCaptureUI^ UnwrapCameraCaptureUI(Local<Value> value);
  
  v8::Local<v8::Value> WrapAppCapture(::Windows::Media::Capture::AppCapture^ wintRtInstance);
  ::Windows::Media::Capture::AppCapture^ UnwrapAppCapture(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCaptureFailedEventArgs(::Windows::Media::Capture::MediaCaptureFailedEventArgs^ wintRtInstance);
  ::Windows::Media::Capture::MediaCaptureFailedEventArgs^ UnwrapMediaCaptureFailedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCapture(::Windows::Media::Capture::MediaCapture^ wintRtInstance);
  ::Windows::Media::Capture::MediaCapture^ UnwrapMediaCapture(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCaptureVideoProfileMediaDescription(::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ wintRtInstance);
  ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ UnwrapMediaCaptureVideoProfileMediaDescription(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCaptureVideoProfile(::Windows::Media::Capture::MediaCaptureVideoProfile^ wintRtInstance);
  ::Windows::Media::Capture::MediaCaptureVideoProfile^ UnwrapMediaCaptureVideoProfile(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCaptureInitializationSettings(::Windows::Media::Capture::MediaCaptureInitializationSettings^ wintRtInstance);
  ::Windows::Media::Capture::MediaCaptureInitializationSettings^ UnwrapMediaCaptureInitializationSettings(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCaptureSettings(::Windows::Media::Capture::MediaCaptureSettings^ wintRtInstance);
  ::Windows::Media::Capture::MediaCaptureSettings^ UnwrapMediaCaptureSettings(Local<Value> value);
  
  v8::Local<v8::Value> WrapLowLagMediaRecording(::Windows::Media::Capture::LowLagMediaRecording^ wintRtInstance);
  ::Windows::Media::Capture::LowLagMediaRecording^ UnwrapLowLagMediaRecording(Local<Value> value);
  
  v8::Local<v8::Value> WrapLowLagPhotoCapture(::Windows::Media::Capture::LowLagPhotoCapture^ wintRtInstance);
  ::Windows::Media::Capture::LowLagPhotoCapture^ UnwrapLowLagPhotoCapture(Local<Value> value);
  
  v8::Local<v8::Value> WrapLowLagPhotoSequenceCapture(::Windows::Media::Capture::LowLagPhotoSequenceCapture^ wintRtInstance);
  ::Windows::Media::Capture::LowLagPhotoSequenceCapture^ UnwrapLowLagPhotoSequenceCapture(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCaptureFocusChangedEventArgs(::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ wintRtInstance);
  ::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ UnwrapMediaCaptureFocusChangedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapPhotoConfirmationCapturedEventArgs(::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ wintRtInstance);
  ::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ UnwrapPhotoConfirmationCapturedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapAdvancedPhotoCapture(::Windows::Media::Capture::AdvancedPhotoCapture^ wintRtInstance);
  ::Windows::Media::Capture::AdvancedPhotoCapture^ UnwrapAdvancedPhotoCapture(Local<Value> value);
  
  v8::Local<v8::Value> WrapCapturedPhoto(::Windows::Media::Capture::CapturedPhoto^ wintRtInstance);
  ::Windows::Media::Capture::CapturedPhoto^ UnwrapCapturedPhoto(Local<Value> value);
  
  v8::Local<v8::Value> WrapAdvancedCapturedPhoto(::Windows::Media::Capture::AdvancedCapturedPhoto^ wintRtInstance);
  ::Windows::Media::Capture::AdvancedCapturedPhoto^ UnwrapAdvancedCapturedPhoto(Local<Value> value);
  
  v8::Local<v8::Value> WrapOptionalReferencePhotoCapturedEventArgs(::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ wintRtInstance);
  ::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ UnwrapOptionalReferencePhotoCapturedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapCapturedFrame(::Windows::Media::Capture::CapturedFrame^ wintRtInstance);
  ::Windows::Media::Capture::CapturedFrame^ UnwrapCapturedFrame(Local<Value> value);
  
  v8::Local<v8::Value> WrapPhotoCapturedEventArgs(::Windows::Media::Capture::PhotoCapturedEventArgs^ wintRtInstance);
  ::Windows::Media::Capture::PhotoCapturedEventArgs^ UnwrapPhotoCapturedEventArgs(Local<Value> value);
  
  v8::Local<v8::Value> WrapCapturedFrameControlValues(::Windows::Media::Capture::CapturedFrameControlValues^ wintRtInstance);
  ::Windows::Media::Capture::CapturedFrameControlValues^ UnwrapCapturedFrameControlValues(Local<Value> value);
  
  v8::Local<v8::Value> WrapVideoStreamConfiguration(::Windows::Media::Capture::VideoStreamConfiguration^ wintRtInstance);
  ::Windows::Media::Capture::VideoStreamConfiguration^ UnwrapVideoStreamConfiguration(Local<Value> value);
  
  v8::Local<v8::Value> WrapAppCaptureSettings(::Windows::Media::Capture::AppCaptureSettings^ wintRtInstance);
  ::Windows::Media::Capture::AppCaptureSettings^ UnwrapAppCaptureSettings(Local<Value> value);
  
  v8::Local<v8::Value> WrapAppCaptureAlternateShortcutKeys(::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ wintRtInstance);
  ::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ UnwrapAppCaptureAlternateShortcutKeys(Local<Value> value);
  
  v8::Local<v8::Value> WrapAppCaptureManager(::Windows::Media::Capture::AppCaptureManager^ wintRtInstance);
  ::Windows::Media::Capture::AppCaptureManager^ UnwrapAppCaptureManager(Local<Value> value);
  
  v8::Local<v8::Value> WrapCameraOptionsUI(::Windows::Media::Capture::CameraOptionsUI^ wintRtInstance);
  ::Windows::Media::Capture::CameraOptionsUI^ UnwrapCameraOptionsUI(Local<Value> value);
  
  v8::Local<v8::Value> WrapScreenCapture(::Windows::Media::Capture::ScreenCapture^ wintRtInstance);
  ::Windows::Media::Capture::ScreenCapture^ UnwrapScreenCapture(Local<Value> value);
  
  v8::Local<v8::Value> WrapSourceSuspensionChangedEventArgs(::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ wintRtInstance);
  ::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ UnwrapSourceSuspensionChangedEventArgs(Local<Value> value);
  


  static void InitCameraCaptureUIModeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("CameraCaptureUIMode").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("photoOrVideo").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMode::PhotoOrVideo)));
	Nan::Set(enumObject, Nan::New<String>("photo").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMode::Photo)));
	Nan::Set(enumObject, Nan::New<String>("video").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMode::Video)));
  }


  static void InitCameraCaptureUIPhotoFormatEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("CameraCaptureUIPhotoFormat").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("jpeg").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIPhotoFormat::Jpeg)));
	Nan::Set(enumObject, Nan::New<String>("png").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIPhotoFormat::Png)));
	Nan::Set(enumObject, Nan::New<String>("jpegXR").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIPhotoFormat::JpegXR)));
  }


  static void InitCameraCaptureUIVideoFormatEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("CameraCaptureUIVideoFormat").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("mp4").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIVideoFormat::Mp4)));
	Nan::Set(enumObject, Nan::New<String>("wmv").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIVideoFormat::Wmv)));
  }


  static void InitCameraCaptureUIMaxVideoResolutionEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("CameraCaptureUIMaxVideoResolution").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("highestAvailable").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxVideoResolution::HighestAvailable)));
	Nan::Set(enumObject, Nan::New<String>("lowDefinition").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxVideoResolution::LowDefinition)));
	Nan::Set(enumObject, Nan::New<String>("standardDefinition").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxVideoResolution::StandardDefinition)));
	Nan::Set(enumObject, Nan::New<String>("highDefinition").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxVideoResolution::HighDefinition)));
  }


  static void InitCameraCaptureUIMaxPhotoResolutionEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("CameraCaptureUIMaxPhotoResolution").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("highestAvailable").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution::HighestAvailable)));
	Nan::Set(enumObject, Nan::New<String>("verySmallQvga").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution::VerySmallQvga)));
	Nan::Set(enumObject, Nan::New<String>("smallVga").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution::SmallVga)));
	Nan::Set(enumObject, Nan::New<String>("mediumXga").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution::MediumXga)));
	Nan::Set(enumObject, Nan::New<String>("large3M").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution::Large3M)));
	Nan::Set(enumObject, Nan::New<String>("veryLarge5M").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution::VeryLarge5M)));
  }


  static void InitMediaCategoryEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("MediaCategory").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("other").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCategory::Other)));
	Nan::Set(enumObject, Nan::New<String>("communications").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCategory::Communications)));
	Nan::Set(enumObject, Nan::New<String>("media").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCategory::Media)));
	Nan::Set(enumObject, Nan::New<String>("gameChat").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCategory::GameChat)));
	Nan::Set(enumObject, Nan::New<String>("speech").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCategory::Speech)));
  }


  static void InitMediaStreamTypeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("MediaStreamType").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("videoPreview").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaStreamType::VideoPreview)));
	Nan::Set(enumObject, Nan::New<String>("videoRecord").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaStreamType::VideoRecord)));
	Nan::Set(enumObject, Nan::New<String>("audio").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaStreamType::Audio)));
	Nan::Set(enumObject, Nan::New<String>("photo").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaStreamType::Photo)));
  }


  static void InitStreamingCaptureModeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("StreamingCaptureMode").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("audioAndVideo").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::StreamingCaptureMode::AudioAndVideo)));
	Nan::Set(enumObject, Nan::New<String>("audio").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::StreamingCaptureMode::Audio)));
	Nan::Set(enumObject, Nan::New<String>("video").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::StreamingCaptureMode::Video)));
  }


  static void InitVideoRotationEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("VideoRotation").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("none").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoRotation::None)));
	Nan::Set(enumObject, Nan::New<String>("clockwise90Degrees").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoRotation::Clockwise90Degrees)));
	Nan::Set(enumObject, Nan::New<String>("clockwise180Degrees").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoRotation::Clockwise180Degrees)));
	Nan::Set(enumObject, Nan::New<String>("clockwise270Degrees").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoRotation::Clockwise270Degrees)));
  }


  static void InitPhotoCaptureSourceEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("PhotoCaptureSource").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("auto").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::PhotoCaptureSource::Auto)));
	Nan::Set(enumObject, Nan::New<String>("videoPreview").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::PhotoCaptureSource::VideoPreview)));
	Nan::Set(enumObject, Nan::New<String>("photo").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::PhotoCaptureSource::Photo)));
  }


  static void InitVideoDeviceCharacteristicEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("VideoDeviceCharacteristic").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("allStreamsIndependent").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIndependent)));
	Nan::Set(enumObject, Nan::New<String>("previewRecordStreamsIdentical").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoDeviceCharacteristic::PreviewRecordStreamsIdentical)));
	Nan::Set(enumObject, Nan::New<String>("previewPhotoStreamsIdentical").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoDeviceCharacteristic::PreviewPhotoStreamsIdentical)));
	Nan::Set(enumObject, Nan::New<String>("recordPhotoStreamsIdentical").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoDeviceCharacteristic::RecordPhotoStreamsIdentical)));
	Nan::Set(enumObject, Nan::New<String>("allStreamsIdentical").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIdentical)));
  }


  static void InitPowerlineFrequencyEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("PowerlineFrequency").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("disabled").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::PowerlineFrequency::Disabled)));
	Nan::Set(enumObject, Nan::New<String>("fiftyHertz").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::PowerlineFrequency::FiftyHertz)));
	Nan::Set(enumObject, Nan::New<String>("sixtyHertz").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::PowerlineFrequency::SixtyHertz)));
  }


  static void InitMediaCaptureThermalStatusEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("MediaCaptureThermalStatus").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("normal").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCaptureThermalStatus::Normal)));
	Nan::Set(enumObject, Nan::New<String>("overheated").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCaptureThermalStatus::Overheated)));
  }


  static void InitKnownVideoProfileEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("KnownVideoProfile").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("videoRecording").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::KnownVideoProfile::VideoRecording)));
	Nan::Set(enumObject, Nan::New<String>("highQualityPhoto").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::KnownVideoProfile::HighQualityPhoto)));
	Nan::Set(enumObject, Nan::New<String>("balancedVideoAndPhoto").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::KnownVideoProfile::BalancedVideoAndPhoto)));
	Nan::Set(enumObject, Nan::New<String>("videoConferencing").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::KnownVideoProfile::VideoConferencing)));
	Nan::Set(enumObject, Nan::New<String>("photoSequence").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::KnownVideoProfile::PhotoSequence)));
  }


  static void InitAppCaptureVideoEncodingBitrateModeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("AppCaptureVideoEncodingBitrateMode").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("custom").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingBitrateMode::Custom)));
	Nan::Set(enumObject, Nan::New<String>("high").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingBitrateMode::High)));
	Nan::Set(enumObject, Nan::New<String>("standard").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingBitrateMode::Standard)));
  }


  static void InitAppCaptureVideoEncodingResolutionModeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("AppCaptureVideoEncodingResolutionMode").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("custom").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingResolutionMode::Custom)));
	Nan::Set(enumObject, Nan::New<String>("high").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingResolutionMode::High)));
	Nan::Set(enumObject, Nan::New<String>("standard").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingResolutionMode::Standard)));
  }


  static void InitAppCaptureHistoricalBufferLengthUnitEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("AppCaptureHistoricalBufferLengthUnit").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("megabytes").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureHistoricalBufferLengthUnit::Megabytes)));
	Nan::Set(enumObject, Nan::New<String>("seconds").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureHistoricalBufferLengthUnit::Seconds)));
  }



  
  static bool IsWhiteBalanceGainJsObject(Local<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    symbol = Nan::New<String>("r").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      if (!Nan::Get(obj,symbol).ToLocalChecked()->IsNumber())
      {
          return false;
      }
    }
    
    symbol = Nan::New<String>("g").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      if (!Nan::Get(obj,symbol).ToLocalChecked()->IsNumber())
      {
          return false;
      }
    }
    
    symbol = Nan::New<String>("b").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      if (!Nan::Get(obj,symbol).ToLocalChecked()->IsNumber())
      {
          return false;
      }
    }
    
    return true;
  }

  ::Windows::Media::Capture::WhiteBalanceGain WhiteBalanceGainFromJsObject(Local<Value> value)
  {
    HandleScope scope;
    ::Windows::Media::Capture::WhiteBalanceGain returnValue;
    
    if (!value->IsObject())
    {
      Nan::ThrowError(Nan::TypeError(NodeRT::Utils::NewString(L"Unexpected type, expected an object")));
      return returnValue;
    }

    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();
    Local<String> symbol;

    symbol = Nan::New<String>("r").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      returnValue.R = Nan::To<double>(Nan::Get(obj,symbol).ToLocalChecked()).FromMaybe(0.0);
    }
    
    symbol = Nan::New<String>("g").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      returnValue.G = Nan::To<double>(Nan::Get(obj,symbol).ToLocalChecked()).FromMaybe(0.0);
    }
    
    symbol = Nan::New<String>("b").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      returnValue.B = Nan::To<double>(Nan::Get(obj,symbol).ToLocalChecked()).FromMaybe(0.0);
    }
    
    return returnValue;
  }

  Local<Value> WhiteBalanceGainToJsObject(::Windows::Media::Capture::WhiteBalanceGain value)
  {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();

    Nan::Set(obj, Nan::New<String>("r").ToLocalChecked(), Nan::New<Number>(static_cast<double>(value.R)));
    Nan::Set(obj, Nan::New<String>("g").ToLocalChecked(), Nan::New<Number>(static_cast<double>(value.G)));
    Nan::Set(obj, Nan::New<String>("b").ToLocalChecked(), Nan::New<Number>(static_cast<double>(value.B)));
    
    return scope.Escape(obj);
  }

  
  static bool IsAppCaptureContractJsObject(Local<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    return true;
  }

  ::Windows::Media::Capture::AppCaptureContract AppCaptureContractFromJsObject(Local<Value> value)
  {
    HandleScope scope;
    ::Windows::Media::Capture::AppCaptureContract returnValue;
    
    if (!value->IsObject())
    {
      Nan::ThrowError(Nan::TypeError(NodeRT::Utils::NewString(L"Unexpected type, expected an object")));
      return returnValue;
    }

    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();
    Local<String> symbol;

    return returnValue;
  }

  Local<Value> AppCaptureContractToJsObject(::Windows::Media::Capture::AppCaptureContract value)
  {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();

    
    return scope.Escape(obj);
  }

  
  static bool IsCameraCaptureUIContractJsObject(Local<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    return true;
  }

  ::Windows::Media::Capture::CameraCaptureUIContract CameraCaptureUIContractFromJsObject(Local<Value> value)
  {
    HandleScope scope;
    ::Windows::Media::Capture::CameraCaptureUIContract returnValue;
    
    if (!value->IsObject())
    {
      Nan::ThrowError(Nan::TypeError(NodeRT::Utils::NewString(L"Unexpected type, expected an object")));
      return returnValue;
    }

    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();
    Local<String> symbol;

    return returnValue;
  }

  Local<Value> CameraCaptureUIContractToJsObject(::Windows::Media::Capture::CameraCaptureUIContract value)
  {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();

    
    return scope.Escape(obj);
  }

  
  static bool IsSizeJsObject(Local<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    return true;
  }

  ::Windows::Foundation::Size SizeFromJsObject(Local<Value> value)
  {
    HandleScope scope;
    ::Windows::Foundation::Size returnValue;
    
    if (!value->IsObject())
    {
      Nan::ThrowError(Nan::TypeError(NodeRT::Utils::NewString(L"Unexpected type, expected an object")));
      return returnValue;
    }

    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();
    Local<String> symbol;

    return returnValue;
  }

  Local<Value> SizeToJsObject(::Windows::Foundation::Size value)
  {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();

    
    return scope.Escape(obj);
  }

  
  class CameraCaptureUIPhotoCaptureSettings : 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>("CameraCaptureUIPhotoCaptureSettings").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxResolution").ToLocalChecked(), MaxResolutionGetter, MaxResolutionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("format").ToLocalChecked(), FormatGetter, FormatSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("croppedSizeInPixels").ToLocalChecked(), CroppedSizeInPixelsGetter, CroppedSizeInPixelsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("croppedAspectRatio").ToLocalChecked(), CroppedAspectRatioGetter, CroppedAspectRatioSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("allowCropping").ToLocalChecked(), AllowCroppingGetter, AllowCroppingSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("CameraCaptureUIPhotoCaptureSettings").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CameraCaptureUIPhotoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ 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::Capture::CameraCaptureUIPhotoCaptureSettings^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^) 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());

      CameraCaptureUIPhotoCaptureSettings *wrapperInstance = new CameraCaptureUIPhotoCaptureSettings(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::Capture::CameraCaptureUIPhotoCaptureSettings^>(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::Capture::CameraCaptureUIPhotoCaptureSettings^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCameraCaptureUIPhotoCaptureSettings(winRtInstance));
    }


  



    static void MaxResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution result = wrapper->_instance->MaxResolution;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxResolutionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution winRtValue = static_cast<::Windows::Media::Capture::CameraCaptureUIMaxPhotoResolution>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->MaxResolution = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void FormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::CameraCaptureUIPhotoFormat result = wrapper->_instance->Format;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FormatSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::CameraCaptureUIPhotoFormat winRtValue = static_cast<::Windows::Media::Capture::CameraCaptureUIPhotoFormat>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Format = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void CroppedSizeInPixelsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->CroppedSizeInPixels;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CroppedSizeInPixelsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsSize(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Foundation::Size winRtValue = NodeRT::Utils::SizeFromJs(value);

        wrapper->_instance->CroppedSizeInPixels = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void CroppedAspectRatioGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->CroppedAspectRatio;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CroppedAspectRatioSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsSize(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Foundation::Size winRtValue = NodeRT::Utils::SizeFromJs(value);

        wrapper->_instance->CroppedAspectRatio = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AllowCroppingGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->AllowCropping;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AllowCroppingSetter(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::Capture::CameraCaptureUIPhotoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIPhotoCaptureSettings *wrapper = CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->AllowCropping = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCameraCaptureUIPhotoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ wintRtInstance);
    friend ::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ UnwrapCameraCaptureUIPhotoCaptureSettings(Local<Value> value);
  };
  Persistent<FunctionTemplate> CameraCaptureUIPhotoCaptureSettings::s_constructorTemplate;

  v8::Local<v8::Value> WrapCameraCaptureUIPhotoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ 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>(CameraCaptureUIPhotoCaptureSettings::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ UnwrapCameraCaptureUIPhotoCaptureSettings(Local<Value> value)
  {
     return CameraCaptureUIPhotoCaptureSettings::Unwrap<CameraCaptureUIPhotoCaptureSettings>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCameraCaptureUIPhotoCaptureSettings(Local<Object> exports)
  {
    CameraCaptureUIPhotoCaptureSettings::Init(exports);
  }

  class CameraCaptureUIVideoCaptureSettings : 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>("CameraCaptureUIVideoCaptureSettings").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxResolution").ToLocalChecked(), MaxResolutionGetter, MaxResolutionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxDurationInSeconds").ToLocalChecked(), MaxDurationInSecondsGetter, MaxDurationInSecondsSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("format").ToLocalChecked(), FormatGetter, FormatSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("allowTrimming").ToLocalChecked(), AllowTrimmingGetter, AllowTrimmingSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("CameraCaptureUIVideoCaptureSettings").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CameraCaptureUIVideoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ 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::Capture::CameraCaptureUIVideoCaptureSettings^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^) 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());

      CameraCaptureUIVideoCaptureSettings *wrapperInstance = new CameraCaptureUIVideoCaptureSettings(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::Capture::CameraCaptureUIVideoCaptureSettings^>(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::Capture::CameraCaptureUIVideoCaptureSettings^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCameraCaptureUIVideoCaptureSettings(winRtInstance));
    }


  



    static void MaxResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::CameraCaptureUIMaxVideoResolution result = wrapper->_instance->MaxResolution;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxResolutionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::CameraCaptureUIMaxVideoResolution winRtValue = static_cast<::Windows::Media::Capture::CameraCaptureUIMaxVideoResolution>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->MaxResolution = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void MaxDurationInSecondsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        float result = wrapper->_instance->MaxDurationInSeconds;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxDurationInSecondsSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsNumber())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        
        float winRtValue = static_cast<float>(Nan::To<double>(value).FromMaybe(0.0));

        wrapper->_instance->MaxDurationInSeconds = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void FormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::CameraCaptureUIVideoFormat result = wrapper->_instance->Format;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FormatSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::CameraCaptureUIVideoFormat winRtValue = static_cast<::Windows::Media::Capture::CameraCaptureUIVideoFormat>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Format = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AllowTrimmingGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->AllowTrimming;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AllowTrimmingSetter(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::Capture::CameraCaptureUIVideoCaptureSettings^>(info.This()))
      {
        return;
      }

      CameraCaptureUIVideoCaptureSettings *wrapper = CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->AllowTrimming = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCameraCaptureUIVideoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ wintRtInstance);
    friend ::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ UnwrapCameraCaptureUIVideoCaptureSettings(Local<Value> value);
  };
  Persistent<FunctionTemplate> CameraCaptureUIVideoCaptureSettings::s_constructorTemplate;

  v8::Local<v8::Value> WrapCameraCaptureUIVideoCaptureSettings(::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ 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>(CameraCaptureUIVideoCaptureSettings::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ UnwrapCameraCaptureUIVideoCaptureSettings(Local<Value> value)
  {
     return CameraCaptureUIVideoCaptureSettings::Unwrap<CameraCaptureUIVideoCaptureSettings>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCameraCaptureUIVideoCaptureSettings(Local<Object> exports)
  {
    CameraCaptureUIVideoCaptureSettings::Init(exports);
  }

  class CameraCaptureUI : 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>("CameraCaptureUI").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
                  
      Nan::SetPrototypeMethod(localRef, "captureFileAsync", CaptureFileAsync);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("photoSettings").ToLocalChecked(), PhotoSettingsGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoSettings").ToLocalChecked(), VideoSettingsGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("CameraCaptureUI").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CameraCaptureUI(::Windows::Media::Capture::CameraCaptureUI^ 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::Capture::CameraCaptureUI^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUI^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::CameraCaptureUI^) 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::Capture::CameraCaptureUI();
        }
        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());

      CameraCaptureUI *wrapperInstance = new CameraCaptureUI(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::Capture::CameraCaptureUI^>(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::Capture::CameraCaptureUI^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::CameraCaptureUI^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCameraCaptureUI(winRtInstance));
    }


    static void CaptureFileAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUI^>(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;
      }

      CameraCaptureUI *wrapper = CameraCaptureUI::Unwrap<CameraCaptureUI>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Storage::StorageFile^>^ op;
    

      if (info.Length() == 2
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Media::Capture::CameraCaptureUIMode arg0 = static_cast<::Windows::Media::Capture::CameraCaptureUIMode>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          op = wrapper->_instance->CaptureFileAsync(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::Storage::StorageFile^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFile", 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 PhotoSettingsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUI^>(info.This()))
      {
        return;
      }

      CameraCaptureUI *wrapper = CameraCaptureUI::Unwrap<CameraCaptureUI>(info.This());

      try 
      {
        ::Windows::Media::Capture::CameraCaptureUIPhotoCaptureSettings^ result = wrapper->_instance->PhotoSettings;
        info.GetReturnValue().Set(WrapCameraCaptureUIPhotoCaptureSettings(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoSettingsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraCaptureUI^>(info.This()))
      {
        return;
      }

      CameraCaptureUI *wrapper = CameraCaptureUI::Unwrap<CameraCaptureUI>(info.This());

      try 
      {
        ::Windows::Media::Capture::CameraCaptureUIVideoCaptureSettings^ result = wrapper->_instance->VideoSettings;
        info.GetReturnValue().Set(WrapCameraCaptureUIVideoCaptureSettings(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::CameraCaptureUI^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCameraCaptureUI(::Windows::Media::Capture::CameraCaptureUI^ wintRtInstance);
    friend ::Windows::Media::Capture::CameraCaptureUI^ UnwrapCameraCaptureUI(Local<Value> value);
  };
  Persistent<FunctionTemplate> CameraCaptureUI::s_constructorTemplate;

  v8::Local<v8::Value> WrapCameraCaptureUI(::Windows::Media::Capture::CameraCaptureUI^ 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>(CameraCaptureUI::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::CameraCaptureUI^ UnwrapCameraCaptureUI(Local<Value> value)
  {
     return CameraCaptureUI::Unwrap<CameraCaptureUI>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCameraCaptureUI(Local<Object> exports)
  {
    CameraCaptureUI::Init(exports);
  }

  class AppCapture : 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>("AppCapture").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                        
      Nan::SetPrototypeMethod(localRef,"addListener", AddListener);
      Nan::SetPrototypeMethod(localRef,"on", AddListener);
      Nan::SetPrototypeMethod(localRef,"removeListener", RemoveListener);
      Nan::SetPrototypeMethod(localRef, "off", RemoveListener);
            
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isCapturingAudio").ToLocalChecked(), IsCapturingAudioGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isCapturingVideo").ToLocalChecked(), IsCapturingVideoGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "getForCurrentView", GetForCurrentView);

      Nan::Set(exports, Nan::New<String>("AppCapture").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    AppCapture(::Windows::Media::Capture::AppCapture^ 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::Capture::AppCapture^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCapture^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::AppCapture^) 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());

      AppCapture *wrapperInstance = new AppCapture(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::Capture::AppCapture^>(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::Capture::AppCapture^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::AppCapture^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapAppCapture(winRtInstance));
    }


  


    static void GetForCurrentView(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Capture::AppCapture^ result;
          result = ::Windows::Media::Capture::AppCapture::GetForCurrentView();
          info.GetReturnValue().Set(WrapAppCapture(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 IsCapturingAudioGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCapture^>(info.This()))
      {
        return;
      }

      AppCapture *wrapper = AppCapture::Unwrap<AppCapture>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsCapturingAudio;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsCapturingVideoGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCapture^>(info.This()))
      {
        return;
      }

      AppCapture *wrapper = AppCapture::Unwrap<AppCapture>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsCapturingVideo;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        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"capturingChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCapture^>(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;
        }
        AppCapture *wrapper = AppCapture::Unwrap<AppCapture>(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->CapturingChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::AppCapture^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Media::Capture::AppCapture^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapAppCapture(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 
      {
        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"capturingChanged", 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"capturingChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCapture^>(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;
          }
          AppCapture *wrapper = AppCapture::Unwrap<AppCapture>(info.This());
          wrapper->_instance->CapturingChanged::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::Capture::AppCapture^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapAppCapture(::Windows::Media::Capture::AppCapture^ wintRtInstance);
    friend ::Windows::Media::Capture::AppCapture^ UnwrapAppCapture(Local<Value> value);
  };
  Persistent<FunctionTemplate> AppCapture::s_constructorTemplate;

  v8::Local<v8::Value> WrapAppCapture(::Windows::Media::Capture::AppCapture^ 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>(AppCapture::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::AppCapture^ UnwrapAppCapture(Local<Value> value)
  {
     return AppCapture::Unwrap<AppCapture>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAppCapture(Local<Object> exports)
  {
    AppCapture::Init(exports);
  }

  class MediaCaptureFailedEventArgs : 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>("MediaCaptureFailedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("code").ToLocalChecked(), CodeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("message").ToLocalChecked(), MessageGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("MediaCaptureFailedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    MediaCaptureFailedEventArgs(::Windows::Media::Capture::MediaCaptureFailedEventArgs^ 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::Capture::MediaCaptureFailedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureFailedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::MediaCaptureFailedEventArgs^) 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());

      MediaCaptureFailedEventArgs *wrapperInstance = new MediaCaptureFailedEventArgs(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::Capture::MediaCaptureFailedEventArgs^>(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::Capture::MediaCaptureFailedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::MediaCaptureFailedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapMediaCaptureFailedEventArgs(winRtInstance));
    }


  



    static void CodeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureFailedEventArgs^>(info.This()))
      {
        return;
      }

      MediaCaptureFailedEventArgs *wrapper = MediaCaptureFailedEventArgs::Unwrap<MediaCaptureFailedEventArgs>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->Code;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MessageGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureFailedEventArgs^>(info.This()))
      {
        return;
      }

      MediaCaptureFailedEventArgs *wrapper = MediaCaptureFailedEventArgs::Unwrap<MediaCaptureFailedEventArgs>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->Message;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::MediaCaptureFailedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapMediaCaptureFailedEventArgs(::Windows::Media::Capture::MediaCaptureFailedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Capture::MediaCaptureFailedEventArgs^ UnwrapMediaCaptureFailedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> MediaCaptureFailedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCaptureFailedEventArgs(::Windows::Media::Capture::MediaCaptureFailedEventArgs^ 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>(MediaCaptureFailedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCaptureFailedEventArgs^ UnwrapMediaCaptureFailedEventArgs(Local<Value> value)
  {
     return MediaCaptureFailedEventArgs::Unwrap<MediaCaptureFailedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCaptureFailedEventArgs(Local<Object> exports)
  {
    MediaCaptureFailedEventArgs::Init(exports);
  }

  class MediaCapture : 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>("MediaCapture").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "setEncoderProperty", SetEncoderProperty);
      Nan::SetPrototypeMethod(localRef, "getEncoderProperty", GetEncoderProperty);
      Nan::SetPrototypeMethod(localRef, "setPreviewMirroring", SetPreviewMirroring);
      Nan::SetPrototypeMethod(localRef, "getPreviewMirroring", GetPreviewMirroring);
      Nan::SetPrototypeMethod(localRef, "setPreviewRotation", SetPreviewRotation);
      Nan::SetPrototypeMethod(localRef, "getPreviewRotation", GetPreviewRotation);
      Nan::SetPrototypeMethod(localRef, "setRecordRotation", SetRecordRotation);
      Nan::SetPrototypeMethod(localRef, "getRecordRotation", GetRecordRotation);
      Nan::SetPrototypeMethod(localRef, "close", Close);
      
            
      Nan::SetPrototypeMethod(localRef, "getPreviewFrameAsync", GetPreviewFrameAsync);
      Nan::SetPrototypeMethod(localRef, "prepareAdvancedPhotoCaptureAsync", PrepareAdvancedPhotoCaptureAsync);
      Nan::SetPrototypeMethod(localRef, "initializeAsync", InitializeAsync);
      Nan::SetPrototypeMethod(localRef, "startRecordToStorageFileAsync", StartRecordToStorageFileAsync);
      Nan::SetPrototypeMethod(localRef, "startRecordToStreamAsync", StartRecordToStreamAsync);
      Nan::SetPrototypeMethod(localRef, "startRecordToCustomSinkAsync", StartRecordToCustomSinkAsync);
      Nan::SetPrototypeMethod(localRef, "stopRecordAsync", StopRecordAsync);
      Nan::SetPrototypeMethod(localRef, "capturePhotoToStorageFileAsync", CapturePhotoToStorageFileAsync);
      Nan::SetPrototypeMethod(localRef, "capturePhotoToStreamAsync", CapturePhotoToStreamAsync);
      Nan::SetPrototypeMethod(localRef, "addEffectAsync", AddEffectAsync);
      Nan::SetPrototypeMethod(localRef, "clearEffectsAsync", ClearEffectsAsync);
      Nan::SetPrototypeMethod(localRef, "startPreviewAsync", StartPreviewAsync);
      Nan::SetPrototypeMethod(localRef, "startPreviewToCustomSinkAsync", StartPreviewToCustomSinkAsync);
      Nan::SetPrototypeMethod(localRef, "stopPreviewAsync", StopPreviewAsync);
      Nan::SetPrototypeMethod(localRef, "prepareLowLagRecordToStorageFileAsync", PrepareLowLagRecordToStorageFileAsync);
      Nan::SetPrototypeMethod(localRef, "prepareLowLagRecordToStreamAsync", PrepareLowLagRecordToStreamAsync);
      Nan::SetPrototypeMethod(localRef, "prepareLowLagRecordToCustomSinkAsync", PrepareLowLagRecordToCustomSinkAsync);
      Nan::SetPrototypeMethod(localRef, "prepareLowLagPhotoCaptureAsync", PrepareLowLagPhotoCaptureAsync);
      Nan::SetPrototypeMethod(localRef, "prepareLowLagPhotoSequenceCaptureAsync", PrepareLowLagPhotoSequenceCaptureAsync);
      Nan::SetPrototypeMethod(localRef, "setEncodingPropertiesAsync", SetEncodingPropertiesAsync);
      Nan::SetPrototypeMethod(localRef, "prepareVariablePhotoSequenceCaptureAsync", PrepareVariablePhotoSequenceCaptureAsync);
      Nan::SetPrototypeMethod(localRef, "addAudioEffectAsync", AddAudioEffectAsync);
      Nan::SetPrototypeMethod(localRef, "addVideoEffectAsync", AddVideoEffectAsync);
      Nan::SetPrototypeMethod(localRef, "pauseRecordAsync", PauseRecordAsync);
      Nan::SetPrototypeMethod(localRef, "resumeRecordAsync", ResumeRecordAsync);
      
            
      Nan::SetPrototypeMethod(localRef,"addListener", AddListener);
      Nan::SetPrototypeMethod(localRef,"on", AddListener);
      Nan::SetPrototypeMethod(localRef,"removeListener", RemoveListener);
      Nan::SetPrototypeMethod(localRef, "off", RemoveListener);
            
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioDeviceController").ToLocalChecked(), AudioDeviceControllerGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("mediaCaptureSettings").ToLocalChecked(), MediaCaptureSettingsGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoDeviceController").ToLocalChecked(), VideoDeviceControllerGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("cameraStreamState").ToLocalChecked(), CameraStreamStateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("thermalStatus").ToLocalChecked(), ThermalStatusGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "isVideoProfileSupported", IsVideoProfileSupported);
      Nan::SetMethod(constructor, "findAllVideoProfiles", FindAllVideoProfiles);
      Nan::SetMethod(constructor, "findConcurrentProfiles", FindConcurrentProfiles);
      Nan::SetMethod(constructor, "findKnownVideoProfiles", FindKnownVideoProfiles);

      Nan::Set(exports, Nan::New<String>("MediaCapture").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    MediaCapture(::Windows::Media::Capture::MediaCapture^ 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::Capture::MediaCapture^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::MediaCapture^) 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::Capture::MediaCapture();
        }
        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());

      MediaCapture *wrapperInstance = new MediaCapture(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::Capture::MediaCapture^>(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::Capture::MediaCapture^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::MediaCapture^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapMediaCapture(winRtInstance));
    }


    static void GetPreviewFrameAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::VideoFrame^>^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetPreviewFrameAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::VideoFrame^>(info[0]))
      {
        try
        {
          ::Windows::Media::VideoFrame^ arg0 = dynamic_cast<::Windows::Media::VideoFrame^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->GetPreviewFrameAsync(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::VideoFrame^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Media", "VideoFrame", 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 PrepareAdvancedPhotoCaptureAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::AdvancedPhotoCapture^>^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::ImageEncodingProperties^>(info[0]))
      {
        try
        {
          ::Windows::Media::MediaProperties::ImageEncodingProperties^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::ImageEncodingProperties^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->PrepareAdvancedPhotoCaptureAsync(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::Capture::AdvancedPhotoCapture^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapAdvancedPhotoCapture(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 InitializeAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->InitializeAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info[0]))
      {
        try
        {
          ::Windows::Media::Capture::MediaCaptureInitializationSettings^ arg0 = UnwrapMediaCaptureInitializationSettings(info[0]);
          
          op = wrapper->_instance->InitializeAsync(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 StartRecordToStorageFileAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::IStorageFile^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::IStorageFile^ arg1 = dynamic_cast<::Windows::Storage::IStorageFile^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->StartRecordToStorageFileAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void StartRecordToStreamAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IRandomAccessStream^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::Streams::IRandomAccessStream^ arg1 = dynamic_cast<::Windows::Storage::Streams::IRandomAccessStream^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->StartRecordToStreamAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void StartRecordToCustomSinkAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::IMediaExtension^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Media::IMediaExtension^ arg1 = dynamic_cast<::Windows::Media::IMediaExtension^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->StartRecordToCustomSinkAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 4
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && info[1]->IsString()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IPropertySet^>(info[2]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          ::Windows::Foundation::Collections::IPropertySet^ arg2 = dynamic_cast<::Windows::Foundation::Collections::IPropertySet^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          op = wrapper->_instance->StartRecordToCustomSinkAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void StopRecordAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StopRecordAsync();
        }
        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 CapturePhotoToStorageFileAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::ImageEncodingProperties^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::IStorageFile^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::ImageEncodingProperties^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::ImageEncodingProperties^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::IStorageFile^ arg1 = dynamic_cast<::Windows::Storage::IStorageFile^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->CapturePhotoToStorageFileAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void CapturePhotoToStreamAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::ImageEncodingProperties^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IRandomAccessStream^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::ImageEncodingProperties^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::ImageEncodingProperties^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::Streams::IRandomAccessStream^ arg1 = dynamic_cast<::Windows::Storage::Streams::IRandomAccessStream^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->CapturePhotoToStreamAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void AddEffectAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 4
        && info[0]->IsInt32()
        && info[1]->IsString()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IPropertySet^>(info[2]))
      {
        try
        {
          ::Windows::Media::Capture::MediaStreamType arg0 = static_cast<::Windows::Media::Capture::MediaStreamType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          ::Windows::Foundation::Collections::IPropertySet^ arg2 = dynamic_cast<::Windows::Foundation::Collections::IPropertySet^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          op = wrapper->_instance->AddEffectAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void ClearEffectsAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 2
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Media::Capture::MediaStreamType arg0 = static_cast<::Windows::Media::Capture::MediaStreamType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          op = wrapper->_instance->ClearEffectsAsync(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 StartPreviewAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StartPreviewAsync();
        }
        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 StartPreviewToCustomSinkAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::IMediaExtension^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Media::IMediaExtension^ arg1 = dynamic_cast<::Windows::Media::IMediaExtension^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->StartPreviewToCustomSinkAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 4
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && info[1]->IsString()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IPropertySet^>(info[2]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          ::Windows::Foundation::Collections::IPropertySet^ arg2 = dynamic_cast<::Windows::Foundation::Collections::IPropertySet^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          op = wrapper->_instance->StartPreviewToCustomSinkAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void StopPreviewAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StopPreviewAsync();
        }
        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 PrepareLowLagRecordToStorageFileAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::LowLagMediaRecording^>^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::IStorageFile^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::IStorageFile^ arg1 = dynamic_cast<::Windows::Storage::IStorageFile^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->PrepareLowLagRecordToStorageFileAsync(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::Capture::LowLagMediaRecording^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapLowLagMediaRecording(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 PrepareLowLagRecordToStreamAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::LowLagMediaRecording^>^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IRandomAccessStream^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Storage::Streams::IRandomAccessStream^ arg1 = dynamic_cast<::Windows::Storage::Streams::IRandomAccessStream^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->PrepareLowLagRecordToStreamAsync(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::Capture::LowLagMediaRecording^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapLowLagMediaRecording(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 PrepareLowLagRecordToCustomSinkAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::LowLagMediaRecording^>^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::IMediaExtension^>(info[1]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Media::IMediaExtension^ arg1 = dynamic_cast<::Windows::Media::IMediaExtension^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->PrepareLowLagRecordToCustomSinkAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 4
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaEncodingProfile^>(info[0])
        && info[1]->IsString()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IPropertySet^>(info[2]))
      {
        try
        {
          ::Windows::Media::MediaProperties::MediaEncodingProfile^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::MediaEncodingProfile^>(NodeRT::Utils::GetObjectInstance(info[0]));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[1])));
          ::Windows::Foundation::Collections::IPropertySet^ arg2 = dynamic_cast<::Windows::Foundation::Collections::IPropertySet^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          op = wrapper->_instance->PrepareLowLagRecordToCustomSinkAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Media::Capture::LowLagMediaRecording^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapLowLagMediaRecording(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 PrepareLowLagPhotoCaptureAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::LowLagPhotoCapture^>^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::ImageEncodingProperties^>(info[0]))
      {
        try
        {
          ::Windows::Media::MediaProperties::ImageEncodingProperties^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::ImageEncodingProperties^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->PrepareLowLagPhotoCaptureAsync(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::Capture::LowLagPhotoCapture^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapLowLagPhotoCapture(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 PrepareLowLagPhotoSequenceCaptureAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::LowLagPhotoSequenceCapture^>^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::ImageEncodingProperties^>(info[0]))
      {
        try
        {
          ::Windows::Media::MediaProperties::ImageEncodingProperties^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::ImageEncodingProperties^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->PrepareLowLagPhotoSequenceCaptureAsync(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::Capture::LowLagPhotoSequenceCapture^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapLowLagPhotoSequenceCapture(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 SetEncodingPropertiesAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 4
        && info[0]->IsInt32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::IMediaEncodingProperties^>(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::MediaPropertySet^>(info[2]))
      {
        try
        {
          ::Windows::Media::Capture::MediaStreamType arg0 = static_cast<::Windows::Media::Capture::MediaStreamType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Windows::Media::MediaProperties::IMediaEncodingProperties^ arg1 = dynamic_cast<::Windows::Media::MediaProperties::IMediaEncodingProperties^>(NodeRT::Utils::GetObjectInstance(info[1]));
          ::Windows::Media::MediaProperties::MediaPropertySet^ arg2 = dynamic_cast<::Windows::Media::MediaProperties::MediaPropertySet^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          op = wrapper->_instance->SetEncodingPropertiesAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> args[] = {Undefined()};

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void PrepareVariablePhotoSequenceCaptureAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::Core::VariablePhotoSequenceCapture^>^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::MediaProperties::ImageEncodingProperties^>(info[0]))
      {
        try
        {
          ::Windows::Media::MediaProperties::ImageEncodingProperties^ arg0 = dynamic_cast<::Windows::Media::MediaProperties::ImageEncodingProperties^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->PrepareVariablePhotoSequenceCaptureAsync(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::Capture::Core::VariablePhotoSequenceCapture^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Capture.Core", "VariablePhotoSequenceCapture", 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 AddAudioEffectAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::IMediaExtension^>^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Effects::IAudioEffectDefinition^>(info[0]))
      {
        try
        {
          ::Windows::Media::Effects::IAudioEffectDefinition^ arg0 = dynamic_cast<::Windows::Media::Effects::IAudioEffectDefinition^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->AddAudioEffectAsync(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::IMediaExtension^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Media", "IMediaExtension", 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 AddVideoEffectAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::IMediaExtension^>^ op;
    

      if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Effects::IVideoEffectDefinition^>(info[0])
        && info[1]->IsInt32())
      {
        try
        {
          ::Windows::Media::Effects::IVideoEffectDefinition^ arg0 = dynamic_cast<::Windows::Media::Effects::IVideoEffectDefinition^>(NodeRT::Utils::GetObjectInstance(info[0]));
          ::Windows::Media::Capture::MediaStreamType arg1 = static_cast<::Windows::Media::Capture::MediaStreamType>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          
          op = wrapper->_instance->AddVideoEffectAsync(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::IMediaExtension^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Media", "IMediaExtension", 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 PauseRecordAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 2
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Media::Devices::MediaCapturePauseBehavior arg0 = static_cast<::Windows::Media::Devices::MediaCapturePauseBehavior>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          op = wrapper->_instance->PauseRecordAsync(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 ResumeRecordAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->ResumeRecordAsync();
        }
        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 SetEncoderProperty(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 3
        && info[0]->IsInt32()
        && NodeRT::Utils::IsGuid(info[1])
        && NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(info[2]))
      {
        try
        {
          ::Windows::Media::Capture::MediaStreamType arg0 = static_cast<::Windows::Media::Capture::MediaStreamType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Platform::Guid arg1 = NodeRT::Utils::GuidFromJs(info[1]);
          ::Platform::Object^ arg2 = dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(info[2]));
          
          wrapper->_instance->SetEncoderProperty(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;
      }
    }
    static void GetEncoderProperty(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 2
        && info[0]->IsInt32()
        && NodeRT::Utils::IsGuid(info[1]))
      {
        try
        {
          ::Windows::Media::Capture::MediaStreamType arg0 = static_cast<::Windows::Media::Capture::MediaStreamType>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Platform::Guid arg1 = NodeRT::Utils::GuidFromJs(info[1]);
          
          ::Platform::Object^ result;
          result = wrapper->_instance->GetEncoderProperty(arg0, arg1);
          info.GetReturnValue().Set(CreateOpaqueWrapper(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 SetPreviewMirroring(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 1
        && info[0]->IsBoolean())
      {
        try
        {
          bool arg0 = Nan::To<bool>(info[0]).FromMaybe(false);
          
          wrapper->_instance->SetPreviewMirroring(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 GetPreviewMirroring(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          bool result;
          result = wrapper->_instance->GetPreviewMirroring();
          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 SetPreviewRotation(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Media::Capture::VideoRotation arg0 = static_cast<::Windows::Media::Capture::VideoRotation>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          wrapper->_instance->SetPreviewRotation(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 GetPreviewRotation(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Capture::VideoRotation result;
          result = wrapper->_instance->GetPreviewRotation();
          info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void SetRecordRotation(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Media::Capture::VideoRotation arg0 = static_cast<::Windows::Media::Capture::VideoRotation>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          wrapper->_instance->SetRecordRotation(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 GetRecordRotation(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Capture::VideoRotation result;
          result = wrapper->_instance->GetRecordRotation();
          info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }
    static void Close(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
	    return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          delete wrapper->_instance;
          wrapper->_instance = nullptr;
		  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 IsVideoProfileSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          bool result;
          result = ::Windows::Media::Capture::MediaCapture::IsVideoProfileSupported(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 FindAllVideoProfiles(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Windows::Foundation::Collections::IVectorView<::Windows::Media::Capture::MediaCaptureVideoProfile^>^ result;
          result = ::Windows::Media::Capture::MediaCapture::FindAllVideoProfiles(arg0);
          info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Media::Capture::MediaCaptureVideoProfile^>::CreateVectorViewWrapper(result, 
            [](::Windows::Media::Capture::MediaCaptureVideoProfile^ val) -> Local<Value> {
              return WrapMediaCaptureVideoProfile(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(value);
            },
            [](Local<Value> value) -> ::Windows::Media::Capture::MediaCaptureVideoProfile^ {
              return UnwrapMediaCaptureVideoProfile(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 FindConcurrentProfiles(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 1
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          ::Windows::Foundation::Collections::IVectorView<::Windows::Media::Capture::MediaCaptureVideoProfile^>^ result;
          result = ::Windows::Media::Capture::MediaCapture::FindConcurrentProfiles(arg0);
          info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Media::Capture::MediaCaptureVideoProfile^>::CreateVectorViewWrapper(result, 
            [](::Windows::Media::Capture::MediaCaptureVideoProfile^ val) -> Local<Value> {
              return WrapMediaCaptureVideoProfile(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(value);
            },
            [](Local<Value> value) -> ::Windows::Media::Capture::MediaCaptureVideoProfile^ {
              return UnwrapMediaCaptureVideoProfile(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 FindKnownVideoProfiles(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 2
        && info[0]->IsString()
        && info[1]->IsInt32())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          ::Windows::Media::Capture::KnownVideoProfile arg1 = static_cast<::Windows::Media::Capture::KnownVideoProfile>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          
          ::Windows::Foundation::Collections::IVectorView<::Windows::Media::Capture::MediaCaptureVideoProfile^>^ result;
          result = ::Windows::Media::Capture::MediaCapture::FindKnownVideoProfiles(arg0, arg1);
          info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Media::Capture::MediaCaptureVideoProfile^>::CreateVectorViewWrapper(result, 
            [](::Windows::Media::Capture::MediaCaptureVideoProfile^ val) -> Local<Value> {
              return WrapMediaCaptureVideoProfile(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(value);
            },
            [](Local<Value> value) -> ::Windows::Media::Capture::MediaCaptureVideoProfile^ {
              return UnwrapMediaCaptureVideoProfile(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 AudioDeviceControllerGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      try 
      {
        ::Windows::Media::Devices::AudioDeviceController^ result = wrapper->_instance->AudioDeviceController;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Devices", "AudioDeviceController", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MediaCaptureSettingsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCaptureSettings^ result = wrapper->_instance->MediaCaptureSettings;
        info.GetReturnValue().Set(WrapMediaCaptureSettings(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoDeviceControllerGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      try 
      {
        ::Windows::Media::Devices::VideoDeviceController^ result = wrapper->_instance->VideoDeviceController;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Devices", "VideoDeviceController", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CameraStreamStateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      try 
      {
        ::Windows::Media::Devices::CameraStreamState result = wrapper->_instance->CameraStreamState;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ThermalStatusGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info.This()))
      {
        return;
      }

      MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCaptureThermalStatus result = wrapper->_instance->ThermalStatus;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        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"failed", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
        }
        MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(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->Failed::add(
            ref new ::Windows::Media::Capture::MediaCaptureFailedEventHandler(
            [callbackObjPtr](::Windows::Media::Capture::MediaCapture^ arg0, ::Windows::Media::Capture::MediaCaptureFailedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapMediaCapture(arg0);
                Local<Value> wrappedArg1 = WrapMediaCaptureFailedEventArgs(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"recordLimitationExceeded", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
        }
        MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(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->RecordLimitationExceeded::add(
            ref new ::Windows::Media::Capture::RecordLimitationExceededEventHandler(
            [callbackObjPtr](::Windows::Media::Capture::MediaCapture^ arg0) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapMediaCapture(arg0);

                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();

                Local<Value> args[] = { wrappedArg0 };
                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"focusChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
        }
        MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(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->FocusChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::MediaCapture^, ::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Capture::MediaCapture^ arg0, ::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapMediaCapture(arg0);
                Local<Value> wrappedArg1 = WrapMediaCaptureFocusChangedEventArgs(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"photoConfirmationCaptured", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
        }
        MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(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->PhotoConfirmationCaptured::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::MediaCapture^, ::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Capture::MediaCapture^ arg0, ::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapMediaCapture(arg0);
                Local<Value> wrappedArg1 = WrapPhotoConfirmationCapturedEventArgs(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"cameraStreamStateChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
        }
        MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(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->CameraStreamStateChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::MediaCapture^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Media::Capture::MediaCapture^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapMediaCapture(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"thermalStatusChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
        }
        MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(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->ThermalStatusChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::MediaCapture^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Media::Capture::MediaCapture^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapMediaCapture(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 
      {
        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"failed", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"recordLimitationExceeded", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"focusChanged", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"photoConfirmationCaptured", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"cameraStreamStateChanged", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"thermalStatusChanged", 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"failed", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
          }
          MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());
          wrapper->_instance->Failed::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"recordLimitationExceeded", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
          }
          MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());
          wrapper->_instance->RecordLimitationExceeded::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"focusChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
          }
          MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());
          wrapper->_instance->FocusChanged::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"photoConfirmationCaptured", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
          }
          MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());
          wrapper->_instance->PhotoConfirmationCaptured::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"cameraStreamStateChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
          }
          MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());
          wrapper->_instance->CameraStreamStateChanged::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"thermalStatusChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(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;
          }
          MediaCapture *wrapper = MediaCapture::Unwrap<MediaCapture>(info.This());
          wrapper->_instance->ThermalStatusChanged::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::Capture::MediaCapture^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapMediaCapture(::Windows::Media::Capture::MediaCapture^ wintRtInstance);
    friend ::Windows::Media::Capture::MediaCapture^ UnwrapMediaCapture(Local<Value> value);
  };
  Persistent<FunctionTemplate> MediaCapture::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCapture(::Windows::Media::Capture::MediaCapture^ 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>(MediaCapture::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCapture^ UnwrapMediaCapture(Local<Value> value)
  {
     return MediaCapture::Unwrap<MediaCapture>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCapture(Local<Object> exports)
  {
    MediaCapture::Init(exports);
  }

  class MediaCaptureVideoProfileMediaDescription : 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>("MediaCaptureVideoProfileMediaDescription").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frameRate").ToLocalChecked(), FrameRateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("height").ToLocalChecked(), HeightGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isHdrVideoSupported").ToLocalChecked(), IsHdrVideoSupportedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isVariablePhotoSequenceSupported").ToLocalChecked(), IsVariablePhotoSequenceSupportedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("width").ToLocalChecked(), WidthGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("MediaCaptureVideoProfileMediaDescription").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    MediaCaptureVideoProfileMediaDescription(::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ 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::Capture::MediaCaptureVideoProfileMediaDescription^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^) 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());

      MediaCaptureVideoProfileMediaDescription *wrapperInstance = new MediaCaptureVideoProfileMediaDescription(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::Capture::MediaCaptureVideoProfileMediaDescription^>(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::Capture::MediaCaptureVideoProfileMediaDescription^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapMediaCaptureVideoProfileMediaDescription(winRtInstance));
    }


  



    static void FrameRateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfileMediaDescription *wrapper = MediaCaptureVideoProfileMediaDescription::Unwrap<MediaCaptureVideoProfileMediaDescription>(info.This());

      try 
      {
        double result = wrapper->_instance->FrameRate;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void HeightGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfileMediaDescription *wrapper = MediaCaptureVideoProfileMediaDescription::Unwrap<MediaCaptureVideoProfileMediaDescription>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->Height;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsHdrVideoSupportedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfileMediaDescription *wrapper = MediaCaptureVideoProfileMediaDescription::Unwrap<MediaCaptureVideoProfileMediaDescription>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsHdrVideoSupported;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsVariablePhotoSequenceSupportedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfileMediaDescription *wrapper = MediaCaptureVideoProfileMediaDescription::Unwrap<MediaCaptureVideoProfileMediaDescription>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsVariablePhotoSequenceSupported;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void WidthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfileMediaDescription *wrapper = MediaCaptureVideoProfileMediaDescription::Unwrap<MediaCaptureVideoProfileMediaDescription>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->Width;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapMediaCaptureVideoProfileMediaDescription(::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ wintRtInstance);
    friend ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ UnwrapMediaCaptureVideoProfileMediaDescription(Local<Value> value);
  };
  Persistent<FunctionTemplate> MediaCaptureVideoProfileMediaDescription::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCaptureVideoProfileMediaDescription(::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ 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>(MediaCaptureVideoProfileMediaDescription::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ UnwrapMediaCaptureVideoProfileMediaDescription(Local<Value> value)
  {
     return MediaCaptureVideoProfileMediaDescription::Unwrap<MediaCaptureVideoProfileMediaDescription>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCaptureVideoProfileMediaDescription(Local<Object> exports)
  {
    MediaCaptureVideoProfileMediaDescription::Init(exports);
  }

  class MediaCaptureVideoProfile : 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>("MediaCaptureVideoProfile").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "getConcurrency", GetConcurrency);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("id").ToLocalChecked(), IdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("supportedPhotoMediaDescription").ToLocalChecked(), SupportedPhotoMediaDescriptionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("supportedPreviewMediaDescription").ToLocalChecked(), SupportedPreviewMediaDescriptionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("supportedRecordMediaDescription").ToLocalChecked(), SupportedRecordMediaDescriptionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoDeviceId").ToLocalChecked(), VideoDeviceIdGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("MediaCaptureVideoProfile").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    MediaCaptureVideoProfile(::Windows::Media::Capture::MediaCaptureVideoProfile^ 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::Capture::MediaCaptureVideoProfile^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::MediaCaptureVideoProfile^) 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());

      MediaCaptureVideoProfile *wrapperInstance = new MediaCaptureVideoProfile(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::Capture::MediaCaptureVideoProfile^>(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::Capture::MediaCaptureVideoProfile^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::MediaCaptureVideoProfile^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapMediaCaptureVideoProfile(winRtInstance));
    }


  
    static void GetConcurrency(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfile *wrapper = MediaCaptureVideoProfile::Unwrap<MediaCaptureVideoProfile>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Foundation::Collections::IVectorView<::Windows::Media::Capture::MediaCaptureVideoProfile^>^ result;
          result = wrapper->_instance->GetConcurrency();
          info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Media::Capture::MediaCaptureVideoProfile^>::CreateVectorViewWrapper(result, 
            [](::Windows::Media::Capture::MediaCaptureVideoProfile^ val) -> Local<Value> {
              return WrapMediaCaptureVideoProfile(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(value);
            },
            [](Local<Value> value) -> ::Windows::Media::Capture::MediaCaptureVideoProfile^ {
              return UnwrapMediaCaptureVideoProfile(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 IdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfile *wrapper = MediaCaptureVideoProfile::Unwrap<MediaCaptureVideoProfile>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->Id;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SupportedPhotoMediaDescriptionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfile *wrapper = MediaCaptureVideoProfile::Unwrap<MediaCaptureVideoProfile>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>^ result = wrapper->_instance->SupportedPhotoMediaDescription;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>::CreateVectorViewWrapper(result, 
            [](::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ val) -> Local<Value> {
              return WrapMediaCaptureVideoProfileMediaDescription(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(value);
            },
            [](Local<Value> value) -> ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ {
              return UnwrapMediaCaptureVideoProfileMediaDescription(value);
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SupportedPreviewMediaDescriptionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfile *wrapper = MediaCaptureVideoProfile::Unwrap<MediaCaptureVideoProfile>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>^ result = wrapper->_instance->SupportedPreviewMediaDescription;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>::CreateVectorViewWrapper(result, 
            [](::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ val) -> Local<Value> {
              return WrapMediaCaptureVideoProfileMediaDescription(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(value);
            },
            [](Local<Value> value) -> ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ {
              return UnwrapMediaCaptureVideoProfileMediaDescription(value);
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SupportedRecordMediaDescriptionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfile *wrapper = MediaCaptureVideoProfile::Unwrap<MediaCaptureVideoProfile>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>^ result = wrapper->_instance->SupportedRecordMediaDescription;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>::CreateVectorViewWrapper(result, 
            [](::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ val) -> Local<Value> {
              return WrapMediaCaptureVideoProfileMediaDescription(val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(value);
            },
            [](Local<Value> value) -> ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ {
              return UnwrapMediaCaptureVideoProfileMediaDescription(value);
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoDeviceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(info.This()))
      {
        return;
      }

      MediaCaptureVideoProfile *wrapper = MediaCaptureVideoProfile::Unwrap<MediaCaptureVideoProfile>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->VideoDeviceId;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::MediaCaptureVideoProfile^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapMediaCaptureVideoProfile(::Windows::Media::Capture::MediaCaptureVideoProfile^ wintRtInstance);
    friend ::Windows::Media::Capture::MediaCaptureVideoProfile^ UnwrapMediaCaptureVideoProfile(Local<Value> value);
  };
  Persistent<FunctionTemplate> MediaCaptureVideoProfile::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCaptureVideoProfile(::Windows::Media::Capture::MediaCaptureVideoProfile^ 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>(MediaCaptureVideoProfile::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCaptureVideoProfile^ UnwrapMediaCaptureVideoProfile(Local<Value> value)
  {
     return MediaCaptureVideoProfile::Unwrap<MediaCaptureVideoProfile>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCaptureVideoProfile(Local<Object> exports)
  {
    MediaCaptureVideoProfile::Init(exports);
  }

  class MediaCaptureInitializationSettings : 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>("MediaCaptureInitializationSettings").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoDeviceId").ToLocalChecked(), VideoDeviceIdGetter, VideoDeviceIdSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("streamingCaptureMode").ToLocalChecked(), StreamingCaptureModeGetter, StreamingCaptureModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("photoCaptureSource").ToLocalChecked(), PhotoCaptureSourceGetter, PhotoCaptureSourceSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioDeviceId").ToLocalChecked(), AudioDeviceIdGetter, AudioDeviceIdSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("mediaCategory").ToLocalChecked(), MediaCategoryGetter, MediaCategorySetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioProcessing").ToLocalChecked(), AudioProcessingGetter, AudioProcessingSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioSource").ToLocalChecked(), AudioSourceGetter, AudioSourceSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoSource").ToLocalChecked(), VideoSourceGetter, VideoSourceSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoProfile").ToLocalChecked(), VideoProfileGetter, VideoProfileSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("recordMediaDescription").ToLocalChecked(), RecordMediaDescriptionGetter, RecordMediaDescriptionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("previewMediaDescription").ToLocalChecked(), PreviewMediaDescriptionGetter, PreviewMediaDescriptionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("photoMediaDescription").ToLocalChecked(), PhotoMediaDescriptionGetter, PhotoMediaDescriptionSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("MediaCaptureInitializationSettings").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    MediaCaptureInitializationSettings(::Windows::Media::Capture::MediaCaptureInitializationSettings^ 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::Capture::MediaCaptureInitializationSettings^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::MediaCaptureInitializationSettings^) 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::Capture::MediaCaptureInitializationSettings();
        }
        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());

      MediaCaptureInitializationSettings *wrapperInstance = new MediaCaptureInitializationSettings(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::Capture::MediaCaptureInitializationSettings^>(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::Capture::MediaCaptureInitializationSettings^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::MediaCaptureInitializationSettings^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapMediaCaptureInitializationSettings(winRtInstance));
    }


  



    static void VideoDeviceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->VideoDeviceId;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoDeviceIdSetter(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::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->VideoDeviceId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void StreamingCaptureModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::StreamingCaptureMode result = wrapper->_instance->StreamingCaptureMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void StreamingCaptureModeSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::StreamingCaptureMode winRtValue = static_cast<::Windows::Media::Capture::StreamingCaptureMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->StreamingCaptureMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void PhotoCaptureSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::PhotoCaptureSource result = wrapper->_instance->PhotoCaptureSource;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PhotoCaptureSourceSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::PhotoCaptureSource winRtValue = static_cast<::Windows::Media::Capture::PhotoCaptureSource>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->PhotoCaptureSource = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AudioDeviceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->AudioDeviceId;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AudioDeviceIdSetter(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::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->AudioDeviceId = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void MediaCategoryGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCategory result = wrapper->_instance->MediaCategory;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MediaCategorySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::MediaCategory winRtValue = static_cast<::Windows::Media::Capture::MediaCategory>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->MediaCategory = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AudioProcessingGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::AudioProcessing result = wrapper->_instance->AudioProcessing;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AudioProcessingSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::AudioProcessing winRtValue = static_cast<::Windows::Media::AudioProcessing>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->AudioProcessing = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AudioSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Core::IMediaSource^ result = wrapper->_instance->AudioSource;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Core", "IMediaSource", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AudioSourceSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::IMediaSource^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Core::IMediaSource^ winRtValue = dynamic_cast<::Windows::Media::Core::IMediaSource^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->AudioSource = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void VideoSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Core::IMediaSource^ result = wrapper->_instance->VideoSource;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Core", "IMediaSource", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoSourceSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Core::IMediaSource^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Core::IMediaSource^ winRtValue = dynamic_cast<::Windows::Media::Core::IMediaSource^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->VideoSource = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void VideoProfileGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCaptureVideoProfile^ result = wrapper->_instance->VideoProfile;
        info.GetReturnValue().Set(WrapMediaCaptureVideoProfile(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoProfileSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfile^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::MediaCaptureVideoProfile^ winRtValue = dynamic_cast<::Windows::Media::Capture::MediaCaptureVideoProfile^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->VideoProfile = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void RecordMediaDescriptionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ result = wrapper->_instance->RecordMediaDescription;
        info.GetReturnValue().Set(WrapMediaCaptureVideoProfileMediaDescription(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void RecordMediaDescriptionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ winRtValue = dynamic_cast<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->RecordMediaDescription = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void PreviewMediaDescriptionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ result = wrapper->_instance->PreviewMediaDescription;
        info.GetReturnValue().Set(WrapMediaCaptureVideoProfileMediaDescription(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PreviewMediaDescriptionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ winRtValue = dynamic_cast<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->PreviewMediaDescription = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void PhotoMediaDescriptionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ result = wrapper->_instance->PhotoMediaDescription;
        info.GetReturnValue().Set(WrapMediaCaptureVideoProfileMediaDescription(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PhotoMediaDescriptionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureInitializationSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureInitializationSettings *wrapper = MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^ winRtValue = dynamic_cast<::Windows::Media::Capture::MediaCaptureVideoProfileMediaDescription^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->PhotoMediaDescription = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Capture::MediaCaptureInitializationSettings^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapMediaCaptureInitializationSettings(::Windows::Media::Capture::MediaCaptureInitializationSettings^ wintRtInstance);
    friend ::Windows::Media::Capture::MediaCaptureInitializationSettings^ UnwrapMediaCaptureInitializationSettings(Local<Value> value);
  };
  Persistent<FunctionTemplate> MediaCaptureInitializationSettings::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCaptureInitializationSettings(::Windows::Media::Capture::MediaCaptureInitializationSettings^ 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>(MediaCaptureInitializationSettings::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCaptureInitializationSettings^ UnwrapMediaCaptureInitializationSettings(Local<Value> value)
  {
     return MediaCaptureInitializationSettings::Unwrap<MediaCaptureInitializationSettings>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCaptureInitializationSettings(Local<Object> exports)
  {
    MediaCaptureInitializationSettings::Init(exports);
  }

  class MediaCaptureSettings : 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>("MediaCaptureSettings").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioDeviceId").ToLocalChecked(), AudioDeviceIdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("photoCaptureSource").ToLocalChecked(), PhotoCaptureSourceGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("streamingCaptureMode").ToLocalChecked(), StreamingCaptureModeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoDeviceCharacteristic").ToLocalChecked(), VideoDeviceCharacteristicGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoDeviceId").ToLocalChecked(), VideoDeviceIdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioProcessing").ToLocalChecked(), AudioProcessingGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("cameraSoundRequiredForRegion").ToLocalChecked(), CameraSoundRequiredForRegionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("concurrentRecordAndPhotoSequenceSupported").ToLocalChecked(), ConcurrentRecordAndPhotoSequenceSupportedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("concurrentRecordAndPhotoSupported").ToLocalChecked(), ConcurrentRecordAndPhotoSupportedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("horizontal35mmEquivalentFocalLength").ToLocalChecked(), Horizontal35mmEquivalentFocalLengthGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("mediaCategory").ToLocalChecked(), MediaCategoryGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("pitchOffsetDegrees").ToLocalChecked(), PitchOffsetDegreesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("vertical35mmEquivalentFocalLength").ToLocalChecked(), Vertical35mmEquivalentFocalLengthGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("MediaCaptureSettings").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    MediaCaptureSettings(::Windows::Media::Capture::MediaCaptureSettings^ 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::Capture::MediaCaptureSettings^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::MediaCaptureSettings^) 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());

      MediaCaptureSettings *wrapperInstance = new MediaCaptureSettings(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::Capture::MediaCaptureSettings^>(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::Capture::MediaCaptureSettings^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::MediaCaptureSettings^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapMediaCaptureSettings(winRtInstance));
    }


  



    static void AudioDeviceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->AudioDeviceId;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PhotoCaptureSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::PhotoCaptureSource result = wrapper->_instance->PhotoCaptureSource;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void StreamingCaptureModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::StreamingCaptureMode result = wrapper->_instance->StreamingCaptureMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoDeviceCharacteristicGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::VideoDeviceCharacteristic result = wrapper->_instance->VideoDeviceCharacteristic;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoDeviceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->VideoDeviceId;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AudioProcessingGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::AudioProcessing result = wrapper->_instance->AudioProcessing;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CameraSoundRequiredForRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->CameraSoundRequiredForRegion;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ConcurrentRecordAndPhotoSequenceSupportedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->ConcurrentRecordAndPhotoSequenceSupported;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ConcurrentRecordAndPhotoSupportedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->ConcurrentRecordAndPhotoSupported;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void Horizontal35mmEquivalentFocalLengthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Platform::IBox<unsigned int>^ result = wrapper->_instance->Horizontal35mmEquivalentFocalLength;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MediaCategoryGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::MediaCategory result = wrapper->_instance->MediaCategory;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PitchOffsetDegreesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Platform::IBox<int>^ result = wrapper->_instance->PitchOffsetDegrees;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void Vertical35mmEquivalentFocalLengthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureSettings^>(info.This()))
      {
        return;
      }

      MediaCaptureSettings *wrapper = MediaCaptureSettings::Unwrap<MediaCaptureSettings>(info.This());

      try 
      {
        ::Platform::IBox<unsigned int>^ result = wrapper->_instance->Vertical35mmEquivalentFocalLength;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::MediaCaptureSettings^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapMediaCaptureSettings(::Windows::Media::Capture::MediaCaptureSettings^ wintRtInstance);
    friend ::Windows::Media::Capture::MediaCaptureSettings^ UnwrapMediaCaptureSettings(Local<Value> value);
  };
  Persistent<FunctionTemplate> MediaCaptureSettings::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCaptureSettings(::Windows::Media::Capture::MediaCaptureSettings^ 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>(MediaCaptureSettings::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCaptureSettings^ UnwrapMediaCaptureSettings(Local<Value> value)
  {
     return MediaCaptureSettings::Unwrap<MediaCaptureSettings>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCaptureSettings(Local<Object> exports)
  {
    MediaCaptureSettings::Init(exports);
  }

  class LowLagMediaRecording : 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>("LowLagMediaRecording").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
                  
      Nan::SetPrototypeMethod(localRef, "startAsync", StartAsync);
      Nan::SetPrototypeMethod(localRef, "stopAsync", StopAsync);
      Nan::SetPrototypeMethod(localRef, "finishAsync", FinishAsync);
      Nan::SetPrototypeMethod(localRef, "pauseAsync", PauseAsync);
      Nan::SetPrototypeMethod(localRef, "resumeAsync", ResumeAsync);
      
                  
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("LowLagMediaRecording").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    LowLagMediaRecording(::Windows::Media::Capture::LowLagMediaRecording^ 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::Capture::LowLagMediaRecording^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagMediaRecording^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::LowLagMediaRecording^) 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());

      LowLagMediaRecording *wrapperInstance = new LowLagMediaRecording(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::Capture::LowLagMediaRecording^>(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::Capture::LowLagMediaRecording^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::LowLagMediaRecording^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapLowLagMediaRecording(winRtInstance));
    }


    static void StartAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagMediaRecording^>(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;
      }

      LowLagMediaRecording *wrapper = LowLagMediaRecording::Unwrap<LowLagMediaRecording>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StartAsync();
        }
        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 StopAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagMediaRecording^>(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;
      }

      LowLagMediaRecording *wrapper = LowLagMediaRecording::Unwrap<LowLagMediaRecording>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StopAsync();
        }
        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 FinishAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagMediaRecording^>(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;
      }

      LowLagMediaRecording *wrapper = LowLagMediaRecording::Unwrap<LowLagMediaRecording>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->FinishAsync();
        }
        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 PauseAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagMediaRecording^>(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;
      }

      LowLagMediaRecording *wrapper = LowLagMediaRecording::Unwrap<LowLagMediaRecording>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 2
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Media::Devices::MediaCapturePauseBehavior arg0 = static_cast<::Windows::Media::Devices::MediaCapturePauseBehavior>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          op = wrapper->_instance->PauseAsync(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 ResumeAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagMediaRecording^>(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;
      }

      LowLagMediaRecording *wrapper = LowLagMediaRecording::Unwrap<LowLagMediaRecording>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->ResumeAsync();
        }
        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::Capture::LowLagMediaRecording^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapLowLagMediaRecording(::Windows::Media::Capture::LowLagMediaRecording^ wintRtInstance);
    friend ::Windows::Media::Capture::LowLagMediaRecording^ UnwrapLowLagMediaRecording(Local<Value> value);
  };
  Persistent<FunctionTemplate> LowLagMediaRecording::s_constructorTemplate;

  v8::Local<v8::Value> WrapLowLagMediaRecording(::Windows::Media::Capture::LowLagMediaRecording^ 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>(LowLagMediaRecording::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::LowLagMediaRecording^ UnwrapLowLagMediaRecording(Local<Value> value)
  {
     return LowLagMediaRecording::Unwrap<LowLagMediaRecording>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitLowLagMediaRecording(Local<Object> exports)
  {
    LowLagMediaRecording::Init(exports);
  }

  class LowLagPhotoCapture : 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>("LowLagPhotoCapture").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
                  
      Nan::SetPrototypeMethod(localRef, "captureAsync", CaptureAsync);
      Nan::SetPrototypeMethod(localRef, "finishAsync", FinishAsync);
      
                  
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("LowLagPhotoCapture").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    LowLagPhotoCapture(::Windows::Media::Capture::LowLagPhotoCapture^ 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::Capture::LowLagPhotoCapture^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoCapture^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::LowLagPhotoCapture^) 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());

      LowLagPhotoCapture *wrapperInstance = new LowLagPhotoCapture(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::Capture::LowLagPhotoCapture^>(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::Capture::LowLagPhotoCapture^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::LowLagPhotoCapture^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapLowLagPhotoCapture(winRtInstance));
    }


    static void CaptureAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoCapture^>(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;
      }

      LowLagPhotoCapture *wrapper = LowLagPhotoCapture::Unwrap<LowLagPhotoCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::CapturedPhoto^>^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->CaptureAsync();
        }
        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::Capture::CapturedPhoto^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapCapturedPhoto(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 FinishAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoCapture^>(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;
      }

      LowLagPhotoCapture *wrapper = LowLagPhotoCapture::Unwrap<LowLagPhotoCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->FinishAsync();
        }
        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::Capture::LowLagPhotoCapture^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapLowLagPhotoCapture(::Windows::Media::Capture::LowLagPhotoCapture^ wintRtInstance);
    friend ::Windows::Media::Capture::LowLagPhotoCapture^ UnwrapLowLagPhotoCapture(Local<Value> value);
  };
  Persistent<FunctionTemplate> LowLagPhotoCapture::s_constructorTemplate;

  v8::Local<v8::Value> WrapLowLagPhotoCapture(::Windows::Media::Capture::LowLagPhotoCapture^ 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>(LowLagPhotoCapture::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::LowLagPhotoCapture^ UnwrapLowLagPhotoCapture(Local<Value> value)
  {
     return LowLagPhotoCapture::Unwrap<LowLagPhotoCapture>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitLowLagPhotoCapture(Local<Object> exports)
  {
    LowLagPhotoCapture::Init(exports);
  }

  class LowLagPhotoSequenceCapture : 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>("LowLagPhotoSequenceCapture").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
                  
      Nan::SetPrototypeMethod(localRef, "startAsync", StartAsync);
      Nan::SetPrototypeMethod(localRef, "stopAsync", StopAsync);
      Nan::SetPrototypeMethod(localRef, "finishAsync", FinishAsync);
      
            
      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>("LowLagPhotoSequenceCapture").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    LowLagPhotoSequenceCapture(::Windows::Media::Capture::LowLagPhotoSequenceCapture^ 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::Capture::LowLagPhotoSequenceCapture^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoSequenceCapture^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::LowLagPhotoSequenceCapture^) 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());

      LowLagPhotoSequenceCapture *wrapperInstance = new LowLagPhotoSequenceCapture(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::Capture::LowLagPhotoSequenceCapture^>(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::Capture::LowLagPhotoSequenceCapture^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::LowLagPhotoSequenceCapture^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapLowLagPhotoSequenceCapture(winRtInstance));
    }


    static void StartAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoSequenceCapture^>(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;
      }

      LowLagPhotoSequenceCapture *wrapper = LowLagPhotoSequenceCapture::Unwrap<LowLagPhotoSequenceCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StartAsync();
        }
        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 StopAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoSequenceCapture^>(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;
      }

      LowLagPhotoSequenceCapture *wrapper = LowLagPhotoSequenceCapture::Unwrap<LowLagPhotoSequenceCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StopAsync();
        }
        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 FinishAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoSequenceCapture^>(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;
      }

      LowLagPhotoSequenceCapture *wrapper = LowLagPhotoSequenceCapture::Unwrap<LowLagPhotoSequenceCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->FinishAsync();
        }
        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 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"photoCaptured", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoSequenceCapture^>(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;
        }
        LowLagPhotoSequenceCapture *wrapper = LowLagPhotoSequenceCapture::Unwrap<LowLagPhotoSequenceCapture>(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->PhotoCaptured::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::LowLagPhotoSequenceCapture^, ::Windows::Media::Capture::PhotoCapturedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Capture::LowLagPhotoSequenceCapture^ arg0, ::Windows::Media::Capture::PhotoCapturedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapLowLagPhotoSequenceCapture(arg0);
                Local<Value> wrappedArg1 = WrapPhotoCapturedEventArgs(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"photoCaptured", 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"photoCaptured", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::LowLagPhotoSequenceCapture^>(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;
          }
          LowLagPhotoSequenceCapture *wrapper = LowLagPhotoSequenceCapture::Unwrap<LowLagPhotoSequenceCapture>(info.This());
          wrapper->_instance->PhotoCaptured::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::Capture::LowLagPhotoSequenceCapture^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapLowLagPhotoSequenceCapture(::Windows::Media::Capture::LowLagPhotoSequenceCapture^ wintRtInstance);
    friend ::Windows::Media::Capture::LowLagPhotoSequenceCapture^ UnwrapLowLagPhotoSequenceCapture(Local<Value> value);
  };
  Persistent<FunctionTemplate> LowLagPhotoSequenceCapture::s_constructorTemplate;

  v8::Local<v8::Value> WrapLowLagPhotoSequenceCapture(::Windows::Media::Capture::LowLagPhotoSequenceCapture^ 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>(LowLagPhotoSequenceCapture::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::LowLagPhotoSequenceCapture^ UnwrapLowLagPhotoSequenceCapture(Local<Value> value)
  {
     return LowLagPhotoSequenceCapture::Unwrap<LowLagPhotoSequenceCapture>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitLowLagPhotoSequenceCapture(Local<Object> exports)
  {
    LowLagPhotoSequenceCapture::Init(exports);
  }

  class MediaCaptureFocusChangedEventArgs : 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>("MediaCaptureFocusChangedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("focusState").ToLocalChecked(), FocusStateGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("MediaCaptureFocusChangedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    MediaCaptureFocusChangedEventArgs(::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ 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::Capture::MediaCaptureFocusChangedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^) 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());

      MediaCaptureFocusChangedEventArgs *wrapperInstance = new MediaCaptureFocusChangedEventArgs(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::Capture::MediaCaptureFocusChangedEventArgs^>(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::Capture::MediaCaptureFocusChangedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapMediaCaptureFocusChangedEventArgs(winRtInstance));
    }


  



    static void FocusStateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^>(info.This()))
      {
        return;
      }

      MediaCaptureFocusChangedEventArgs *wrapper = MediaCaptureFocusChangedEventArgs::Unwrap<MediaCaptureFocusChangedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Devices::MediaCaptureFocusState result = wrapper->_instance->FocusState;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapMediaCaptureFocusChangedEventArgs(::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ UnwrapMediaCaptureFocusChangedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> MediaCaptureFocusChangedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCaptureFocusChangedEventArgs(::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ 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>(MediaCaptureFocusChangedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCaptureFocusChangedEventArgs^ UnwrapMediaCaptureFocusChangedEventArgs(Local<Value> value)
  {
     return MediaCaptureFocusChangedEventArgs::Unwrap<MediaCaptureFocusChangedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCaptureFocusChangedEventArgs(Local<Object> exports)
  {
    MediaCaptureFocusChangedEventArgs::Init(exports);
  }

  class PhotoConfirmationCapturedEventArgs : 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>("PhotoConfirmationCapturedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("captureTimeOffset").ToLocalChecked(), CaptureTimeOffsetGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frame").ToLocalChecked(), FrameGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PhotoConfirmationCapturedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PhotoConfirmationCapturedEventArgs(::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ 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::Capture::PhotoConfirmationCapturedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^) 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());

      PhotoConfirmationCapturedEventArgs *wrapperInstance = new PhotoConfirmationCapturedEventArgs(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::Capture::PhotoConfirmationCapturedEventArgs^>(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::Capture::PhotoConfirmationCapturedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPhotoConfirmationCapturedEventArgs(winRtInstance));
    }


  



    static void CaptureTimeOffsetGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^>(info.This()))
      {
        return;
      }

      PhotoConfirmationCapturedEventArgs *wrapper = PhotoConfirmationCapturedEventArgs::Unwrap<PhotoConfirmationCapturedEventArgs>(info.This());

      try 
      {
        ::Windows::Foundation::TimeSpan result = wrapper->_instance->CaptureTimeOffset;
        info.GetReturnValue().Set(Nan::New<Number>(result.Duration/10000.0));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FrameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^>(info.This()))
      {
        return;
      }

      PhotoConfirmationCapturedEventArgs *wrapper = PhotoConfirmationCapturedEventArgs::Unwrap<PhotoConfirmationCapturedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Capture::CapturedFrame^ result = wrapper->_instance->Frame;
        info.GetReturnValue().Set(WrapCapturedFrame(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPhotoConfirmationCapturedEventArgs(::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ UnwrapPhotoConfirmationCapturedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> PhotoConfirmationCapturedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapPhotoConfirmationCapturedEventArgs(::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ 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>(PhotoConfirmationCapturedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::PhotoConfirmationCapturedEventArgs^ UnwrapPhotoConfirmationCapturedEventArgs(Local<Value> value)
  {
     return PhotoConfirmationCapturedEventArgs::Unwrap<PhotoConfirmationCapturedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPhotoConfirmationCapturedEventArgs(Local<Object> exports)
  {
    PhotoConfirmationCapturedEventArgs::Init(exports);
  }

  class AdvancedPhotoCapture : 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>("AdvancedPhotoCapture").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
                  
      Nan::SetPrototypeMethod(localRef, "captureAsync", CaptureAsync);
      Nan::SetPrototypeMethod(localRef, "finishAsync", FinishAsync);
      
            
      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>("AdvancedPhotoCapture").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    AdvancedPhotoCapture(::Windows::Media::Capture::AdvancedPhotoCapture^ 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::Capture::AdvancedPhotoCapture^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedPhotoCapture^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::AdvancedPhotoCapture^) 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());

      AdvancedPhotoCapture *wrapperInstance = new AdvancedPhotoCapture(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::Capture::AdvancedPhotoCapture^>(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::Capture::AdvancedPhotoCapture^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::AdvancedPhotoCapture^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapAdvancedPhotoCapture(winRtInstance));
    }


    static void CaptureAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedPhotoCapture^>(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;
      }

      AdvancedPhotoCapture *wrapper = AdvancedPhotoCapture::Unwrap<AdvancedPhotoCapture>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Media::Capture::AdvancedCapturedPhoto^>^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->CaptureAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(info[0]))
      {
        try
        {
          ::Platform::Object^ arg0 = dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->CaptureAsync(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::Capture::AdvancedCapturedPhoto^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapAdvancedCapturedPhoto(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 FinishAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedPhotoCapture^>(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;
      }

      AdvancedPhotoCapture *wrapper = AdvancedPhotoCapture::Unwrap<AdvancedPhotoCapture>(info.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->FinishAsync();
        }
        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 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"allPhotosCaptured", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedPhotoCapture^>(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;
        }
        AdvancedPhotoCapture *wrapper = AdvancedPhotoCapture::Unwrap<AdvancedPhotoCapture>(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->AllPhotosCaptured::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::AdvancedPhotoCapture^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Media::Capture::AdvancedPhotoCapture^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapAdvancedPhotoCapture(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"optionalReferencePhotoCaptured", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedPhotoCapture^>(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;
        }
        AdvancedPhotoCapture *wrapper = AdvancedPhotoCapture::Unwrap<AdvancedPhotoCapture>(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->OptionalReferencePhotoCaptured::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::AdvancedPhotoCapture^, ::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Capture::AdvancedPhotoCapture^ arg0, ::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapAdvancedPhotoCapture(arg0);
                Local<Value> wrappedArg1 = WrapOptionalReferencePhotoCapturedEventArgs(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"allPhotosCaptured", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"optionalReferencePhotoCaptured", 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"allPhotosCaptured", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedPhotoCapture^>(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;
          }
          AdvancedPhotoCapture *wrapper = AdvancedPhotoCapture::Unwrap<AdvancedPhotoCapture>(info.This());
          wrapper->_instance->AllPhotosCaptured::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionalReferencePhotoCaptured", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedPhotoCapture^>(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;
          }
          AdvancedPhotoCapture *wrapper = AdvancedPhotoCapture::Unwrap<AdvancedPhotoCapture>(info.This());
          wrapper->_instance->OptionalReferencePhotoCaptured::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::Capture::AdvancedPhotoCapture^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapAdvancedPhotoCapture(::Windows::Media::Capture::AdvancedPhotoCapture^ wintRtInstance);
    friend ::Windows::Media::Capture::AdvancedPhotoCapture^ UnwrapAdvancedPhotoCapture(Local<Value> value);
  };
  Persistent<FunctionTemplate> AdvancedPhotoCapture::s_constructorTemplate;

  v8::Local<v8::Value> WrapAdvancedPhotoCapture(::Windows::Media::Capture::AdvancedPhotoCapture^ 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>(AdvancedPhotoCapture::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::AdvancedPhotoCapture^ UnwrapAdvancedPhotoCapture(Local<Value> value)
  {
     return AdvancedPhotoCapture::Unwrap<AdvancedPhotoCapture>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAdvancedPhotoCapture(Local<Object> exports)
  {
    AdvancedPhotoCapture::Init(exports);
  }

  class CapturedPhoto : 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>("CapturedPhoto").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frame").ToLocalChecked(), FrameGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("thumbnail").ToLocalChecked(), ThumbnailGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("CapturedPhoto").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CapturedPhoto(::Windows::Media::Capture::CapturedPhoto^ 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::Capture::CapturedPhoto^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedPhoto^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::CapturedPhoto^) 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());

      CapturedPhoto *wrapperInstance = new CapturedPhoto(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::Capture::CapturedPhoto^>(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::Capture::CapturedPhoto^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::CapturedPhoto^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCapturedPhoto(winRtInstance));
    }


  



    static void FrameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedPhoto^>(info.This()))
      {
        return;
      }

      CapturedPhoto *wrapper = CapturedPhoto::Unwrap<CapturedPhoto>(info.This());

      try 
      {
        ::Windows::Media::Capture::CapturedFrame^ result = wrapper->_instance->Frame;
        info.GetReturnValue().Set(WrapCapturedFrame(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ThumbnailGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedPhoto^>(info.This()))
      {
        return;
      }

      CapturedPhoto *wrapper = CapturedPhoto::Unwrap<CapturedPhoto>(info.This());

      try 
      {
        ::Windows::Media::Capture::CapturedFrame^ result = wrapper->_instance->Thumbnail;
        info.GetReturnValue().Set(WrapCapturedFrame(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::CapturedPhoto^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCapturedPhoto(::Windows::Media::Capture::CapturedPhoto^ wintRtInstance);
    friend ::Windows::Media::Capture::CapturedPhoto^ UnwrapCapturedPhoto(Local<Value> value);
  };
  Persistent<FunctionTemplate> CapturedPhoto::s_constructorTemplate;

  v8::Local<v8::Value> WrapCapturedPhoto(::Windows::Media::Capture::CapturedPhoto^ 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>(CapturedPhoto::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::CapturedPhoto^ UnwrapCapturedPhoto(Local<Value> value)
  {
     return CapturedPhoto::Unwrap<CapturedPhoto>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCapturedPhoto(Local<Object> exports)
  {
    CapturedPhoto::Init(exports);
  }

  class AdvancedCapturedPhoto : 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>("AdvancedCapturedPhoto").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("context").ToLocalChecked(), ContextGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frame").ToLocalChecked(), FrameGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("mode").ToLocalChecked(), ModeGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("AdvancedCapturedPhoto").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    AdvancedCapturedPhoto(::Windows::Media::Capture::AdvancedCapturedPhoto^ 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::Capture::AdvancedCapturedPhoto^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedCapturedPhoto^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::AdvancedCapturedPhoto^) 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());

      AdvancedCapturedPhoto *wrapperInstance = new AdvancedCapturedPhoto(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::Capture::AdvancedCapturedPhoto^>(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::Capture::AdvancedCapturedPhoto^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::AdvancedCapturedPhoto^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapAdvancedCapturedPhoto(winRtInstance));
    }


  



    static void ContextGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedCapturedPhoto^>(info.This()))
      {
        return;
      }

      AdvancedCapturedPhoto *wrapper = AdvancedCapturedPhoto::Unwrap<AdvancedCapturedPhoto>(info.This());

      try 
      {
        ::Platform::Object^ result = wrapper->_instance->Context;
        info.GetReturnValue().Set(CreateOpaqueWrapper(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FrameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedCapturedPhoto^>(info.This()))
      {
        return;
      }

      AdvancedCapturedPhoto *wrapper = AdvancedCapturedPhoto::Unwrap<AdvancedCapturedPhoto>(info.This());

      try 
      {
        ::Windows::Media::Capture::CapturedFrame^ result = wrapper->_instance->Frame;
        info.GetReturnValue().Set(WrapCapturedFrame(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AdvancedCapturedPhoto^>(info.This()))
      {
        return;
      }

      AdvancedCapturedPhoto *wrapper = AdvancedCapturedPhoto::Unwrap<AdvancedCapturedPhoto>(info.This());

      try 
      {
        ::Windows::Media::Devices::AdvancedPhotoMode result = wrapper->_instance->Mode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::AdvancedCapturedPhoto^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapAdvancedCapturedPhoto(::Windows::Media::Capture::AdvancedCapturedPhoto^ wintRtInstance);
    friend ::Windows::Media::Capture::AdvancedCapturedPhoto^ UnwrapAdvancedCapturedPhoto(Local<Value> value);
  };
  Persistent<FunctionTemplate> AdvancedCapturedPhoto::s_constructorTemplate;

  v8::Local<v8::Value> WrapAdvancedCapturedPhoto(::Windows::Media::Capture::AdvancedCapturedPhoto^ 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>(AdvancedCapturedPhoto::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::AdvancedCapturedPhoto^ UnwrapAdvancedCapturedPhoto(Local<Value> value)
  {
     return AdvancedCapturedPhoto::Unwrap<AdvancedCapturedPhoto>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAdvancedCapturedPhoto(Local<Object> exports)
  {
    AdvancedCapturedPhoto::Init(exports);
  }

  class OptionalReferencePhotoCapturedEventArgs : 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>("OptionalReferencePhotoCapturedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("context").ToLocalChecked(), ContextGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frame").ToLocalChecked(), FrameGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("OptionalReferencePhotoCapturedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    OptionalReferencePhotoCapturedEventArgs(::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ 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::Capture::OptionalReferencePhotoCapturedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^) 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());

      OptionalReferencePhotoCapturedEventArgs *wrapperInstance = new OptionalReferencePhotoCapturedEventArgs(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::Capture::OptionalReferencePhotoCapturedEventArgs^>(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::Capture::OptionalReferencePhotoCapturedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapOptionalReferencePhotoCapturedEventArgs(winRtInstance));
    }


  



    static void ContextGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^>(info.This()))
      {
        return;
      }

      OptionalReferencePhotoCapturedEventArgs *wrapper = OptionalReferencePhotoCapturedEventArgs::Unwrap<OptionalReferencePhotoCapturedEventArgs>(info.This());

      try 
      {
        ::Platform::Object^ result = wrapper->_instance->Context;
        info.GetReturnValue().Set(CreateOpaqueWrapper(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FrameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^>(info.This()))
      {
        return;
      }

      OptionalReferencePhotoCapturedEventArgs *wrapper = OptionalReferencePhotoCapturedEventArgs::Unwrap<OptionalReferencePhotoCapturedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Capture::CapturedFrame^ result = wrapper->_instance->Frame;
        info.GetReturnValue().Set(WrapCapturedFrame(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapOptionalReferencePhotoCapturedEventArgs(::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ UnwrapOptionalReferencePhotoCapturedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> OptionalReferencePhotoCapturedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapOptionalReferencePhotoCapturedEventArgs(::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ 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>(OptionalReferencePhotoCapturedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::OptionalReferencePhotoCapturedEventArgs^ UnwrapOptionalReferencePhotoCapturedEventArgs(Local<Value> value)
  {
     return OptionalReferencePhotoCapturedEventArgs::Unwrap<OptionalReferencePhotoCapturedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitOptionalReferencePhotoCapturedEventArgs(Local<Object> exports)
  {
    OptionalReferencePhotoCapturedEventArgs::Init(exports);
  }

  class CapturedFrame : 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>("CapturedFrame").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "getInputStreamAt", GetInputStreamAt);
      Nan::SetPrototypeMethod(localRef, "getOutputStreamAt", GetOutputStreamAt);
      Nan::SetPrototypeMethod(localRef, "seek", Seek);
      Nan::SetPrototypeMethod(localRef, "cloneStream", CloneStream);
      Nan::SetPrototypeMethod(localRef, "close", Close);
      
            
      Nan::SetPrototypeMethod(localRef, "readAsync", ReadAsync);
      Nan::SetPrototypeMethod(localRef, "writeAsync", WriteAsync);
      Nan::SetPrototypeMethod(localRef, "flushAsync", FlushAsync);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("height").ToLocalChecked(), HeightGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("width").ToLocalChecked(), WidthGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("softwareBitmap").ToLocalChecked(), SoftwareBitmapGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contentType").ToLocalChecked(), ContentTypeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("size").ToLocalChecked(), SizeGetter, SizeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("canRead").ToLocalChecked(), CanReadGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("canWrite").ToLocalChecked(), CanWriteGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("position").ToLocalChecked(), PositionGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("CapturedFrame").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CapturedFrame(::Windows::Media::Capture::CapturedFrame^ 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::Capture::CapturedFrame^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::CapturedFrame^) 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());

      CapturedFrame *wrapperInstance = new CapturedFrame(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::Capture::CapturedFrame^>(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::Capture::CapturedFrame^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::CapturedFrame^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCapturedFrame(winRtInstance));
    }


    static void ReadAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(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;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      ::Windows::Foundation::IAsyncOperationWithProgress<::Windows::Storage::Streams::IBuffer^, unsigned int>^ op;
    

      if (info.Length() == 4
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0])
        && info[1]->IsUint32()
        && info[2]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          unsigned int arg1 = static_cast<unsigned int>(Nan::To<uint32_t>(info[1]).FromMaybe(0));
          ::Windows::Storage::Streams::InputStreamOptions arg2 = static_cast<::Windows::Storage::Streams::InputStreamOptions>(Nan::To<int32_t>(info[2]).FromMaybe(0));
          
          op = wrapper->_instance->ReadAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Storage::Streams::IBuffer^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// 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 WriteAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(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;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      ::Windows::Foundation::IAsyncOperationWithProgress<unsigned int, unsigned int>^ op;
    

      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IBuffer^>(info[0]))
      {
        try
        {
          ::Windows::Storage::Streams::IBuffer^ arg0 = dynamic_cast<::Windows::Storage::Streams::IBuffer^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->WriteAsync(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<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = Nan::New<Integer>(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 FlushAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(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;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      ::Windows::Foundation::IAsyncOperation<bool>^ op;
    

      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->FlushAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(info[info.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<bool> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = Nan::New<Boolean>(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// 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 GetInputStreamAt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          ::Windows::Storage::Streams::IInputStream^ result;
          result = wrapper->_instance->GetInputStreamAt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IInputStream", 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 GetOutputStreamAt(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          ::Windows::Storage::Streams::IOutputStream^ result;
          result = wrapper->_instance->GetOutputStreamAt(arg0);
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IOutputStream", 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 Seek(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      if (info.Length() == 1
        && info[0]->IsNumber())
      {
        try
        {
          unsigned __int64 arg0 = static_cast<unsigned __int64>(Nan::To<int64_t>(info[0]).FromMaybe(0));
          
          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 CloneStream(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Streams::IRandomAccessStream^ result;
          result = wrapper->_instance->CloneStream();
          info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IRandomAccessStream", 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 Close(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
	    return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      if (info.Length() == 0)
      {
        try
        {
          delete wrapper->_instance;
          wrapper->_instance = nullptr;
		  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 HeightGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->Height;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void WidthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->Width;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SoftwareBitmapGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        ::Windows::Graphics::Imaging::SoftwareBitmap^ result = wrapper->_instance->SoftwareBitmap;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Graphics.Imaging", "SoftwareBitmap", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ContentTypeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ContentType;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SizeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        unsigned __int64 result = wrapper->_instance->Size;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SizeSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsNumber())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        
        unsigned __int64 winRtValue = static_cast<unsigned __int64>(Nan::To<int64_t>(value).FromMaybe(0));

        wrapper->_instance->Size = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void CanReadGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        bool result = wrapper->_instance->CanRead;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CanWriteGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        bool result = wrapper->_instance->CanWrite;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PositionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrame^>(info.This()))
      {
        return;
      }

      CapturedFrame *wrapper = CapturedFrame::Unwrap<CapturedFrame>(info.This());

      try 
      {
        unsigned __int64 result = wrapper->_instance->Position;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::CapturedFrame^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCapturedFrame(::Windows::Media::Capture::CapturedFrame^ wintRtInstance);
    friend ::Windows::Media::Capture::CapturedFrame^ UnwrapCapturedFrame(Local<Value> value);
  };
  Persistent<FunctionTemplate> CapturedFrame::s_constructorTemplate;

  v8::Local<v8::Value> WrapCapturedFrame(::Windows::Media::Capture::CapturedFrame^ 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>(CapturedFrame::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::CapturedFrame^ UnwrapCapturedFrame(Local<Value> value)
  {
     return CapturedFrame::Unwrap<CapturedFrame>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCapturedFrame(Local<Object> exports)
  {
    CapturedFrame::Init(exports);
  }

  class PhotoCapturedEventArgs : 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>("PhotoCapturedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("captureTimeOffset").ToLocalChecked(), CaptureTimeOffsetGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frame").ToLocalChecked(), FrameGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("thumbnail").ToLocalChecked(), ThumbnailGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("PhotoCapturedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    PhotoCapturedEventArgs(::Windows::Media::Capture::PhotoCapturedEventArgs^ 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::Capture::PhotoCapturedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::PhotoCapturedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::PhotoCapturedEventArgs^) 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());

      PhotoCapturedEventArgs *wrapperInstance = new PhotoCapturedEventArgs(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::Capture::PhotoCapturedEventArgs^>(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::Capture::PhotoCapturedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::PhotoCapturedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapPhotoCapturedEventArgs(winRtInstance));
    }


  



    static void CaptureTimeOffsetGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::PhotoCapturedEventArgs^>(info.This()))
      {
        return;
      }

      PhotoCapturedEventArgs *wrapper = PhotoCapturedEventArgs::Unwrap<PhotoCapturedEventArgs>(info.This());

      try 
      {
        ::Windows::Foundation::TimeSpan result = wrapper->_instance->CaptureTimeOffset;
        info.GetReturnValue().Set(Nan::New<Number>(result.Duration/10000.0));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FrameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::PhotoCapturedEventArgs^>(info.This()))
      {
        return;
      }

      PhotoCapturedEventArgs *wrapper = PhotoCapturedEventArgs::Unwrap<PhotoCapturedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Capture::CapturedFrame^ result = wrapper->_instance->Frame;
        info.GetReturnValue().Set(WrapCapturedFrame(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ThumbnailGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::PhotoCapturedEventArgs^>(info.This()))
      {
        return;
      }

      PhotoCapturedEventArgs *wrapper = PhotoCapturedEventArgs::Unwrap<PhotoCapturedEventArgs>(info.This());

      try 
      {
        ::Windows::Media::Capture::CapturedFrame^ result = wrapper->_instance->Thumbnail;
        info.GetReturnValue().Set(WrapCapturedFrame(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::PhotoCapturedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapPhotoCapturedEventArgs(::Windows::Media::Capture::PhotoCapturedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Capture::PhotoCapturedEventArgs^ UnwrapPhotoCapturedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> PhotoCapturedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapPhotoCapturedEventArgs(::Windows::Media::Capture::PhotoCapturedEventArgs^ 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>(PhotoCapturedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::PhotoCapturedEventArgs^ UnwrapPhotoCapturedEventArgs(Local<Value> value)
  {
     return PhotoCapturedEventArgs::Unwrap<PhotoCapturedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitPhotoCapturedEventArgs(Local<Object> exports)
  {
    PhotoCapturedEventArgs::Init(exports);
  }

  class CapturedFrameControlValues : 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>("CapturedFrameControlValues").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("exposure").ToLocalChecked(), ExposureGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("exposureCompensation").ToLocalChecked(), ExposureCompensationGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("flashPowerPercent").ToLocalChecked(), FlashPowerPercentGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("flashed").ToLocalChecked(), FlashedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("focus").ToLocalChecked(), FocusGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isoSpeed").ToLocalChecked(), IsoSpeedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("sceneMode").ToLocalChecked(), SceneModeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("whiteBalance").ToLocalChecked(), WhiteBalanceGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("zoomFactor").ToLocalChecked(), ZoomFactorGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("focusState").ToLocalChecked(), FocusStateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isoAnalogGain").ToLocalChecked(), IsoAnalogGainGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isoDigitalGain").ToLocalChecked(), IsoDigitalGainGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("sensorFrameRate").ToLocalChecked(), SensorFrameRateGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("whiteBalanceGain").ToLocalChecked(), WhiteBalanceGainGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("CapturedFrameControlValues").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CapturedFrameControlValues(::Windows::Media::Capture::CapturedFrameControlValues^ 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::Capture::CapturedFrameControlValues^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::CapturedFrameControlValues^) 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());

      CapturedFrameControlValues *wrapperInstance = new CapturedFrameControlValues(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::Capture::CapturedFrameControlValues^>(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::Capture::CapturedFrameControlValues^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::CapturedFrameControlValues^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCapturedFrameControlValues(winRtInstance));
    }


  



    static void ExposureGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<::Windows::Foundation::TimeSpan>^ result = wrapper->_instance->Exposure;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(result->Value.Duration/10000.0)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ExposureCompensationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<float>^ result = wrapper->_instance->ExposureCompensation;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FlashPowerPercentGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<float>^ result = wrapper->_instance->FlashPowerPercent;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FlashedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<bool>^ result = wrapper->_instance->Flashed;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Boolean>(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FocusGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<unsigned int>^ result = wrapper->_instance->Focus;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsoSpeedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<unsigned int>^ result = wrapper->_instance->IsoSpeed;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SceneModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<::Windows::Media::Devices::CaptureSceneMode>^ result = wrapper->_instance->SceneMode;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(static_cast<int>(result->Value))) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void WhiteBalanceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<unsigned int>^ result = wrapper->_instance->WhiteBalance;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ZoomFactorGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<float>^ result = wrapper->_instance->ZoomFactor;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FocusStateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<::Windows::Media::Devices::MediaCaptureFocusState>^ result = wrapper->_instance->FocusState;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Integer>(static_cast<int>(result->Value))) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsoAnalogGainGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<double>^ result = wrapper->_instance->IsoAnalogGain;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsoDigitalGainGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<double>^ result = wrapper->_instance->IsoDigitalGain;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(Nan::New<Number>(static_cast<double>(result->Value))) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SensorFrameRateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Windows::Media::MediaProperties::MediaRatio^ result = wrapper->_instance->SensorFrameRate;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.MediaProperties", "MediaRatio", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void WhiteBalanceGainGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CapturedFrameControlValues^>(info.This()))
      {
        return;
      }

      CapturedFrameControlValues *wrapper = CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(info.This());

      try 
      {
        ::Platform::IBox<::Windows::Media::Capture::WhiteBalanceGain>^ result = wrapper->_instance->WhiteBalanceGain;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(WhiteBalanceGainToJsObject(result->Value)) : Undefined());
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::CapturedFrameControlValues^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCapturedFrameControlValues(::Windows::Media::Capture::CapturedFrameControlValues^ wintRtInstance);
    friend ::Windows::Media::Capture::CapturedFrameControlValues^ UnwrapCapturedFrameControlValues(Local<Value> value);
  };
  Persistent<FunctionTemplate> CapturedFrameControlValues::s_constructorTemplate;

  v8::Local<v8::Value> WrapCapturedFrameControlValues(::Windows::Media::Capture::CapturedFrameControlValues^ 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>(CapturedFrameControlValues::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::CapturedFrameControlValues^ UnwrapCapturedFrameControlValues(Local<Value> value)
  {
     return CapturedFrameControlValues::Unwrap<CapturedFrameControlValues>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCapturedFrameControlValues(Local<Object> exports)
  {
    CapturedFrameControlValues::Init(exports);
  }

  class VideoStreamConfiguration : 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>("VideoStreamConfiguration").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("inputProperties").ToLocalChecked(), InputPropertiesGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("outputProperties").ToLocalChecked(), OutputPropertiesGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("VideoStreamConfiguration").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    VideoStreamConfiguration(::Windows::Media::Capture::VideoStreamConfiguration^ 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::Capture::VideoStreamConfiguration^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::VideoStreamConfiguration^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::VideoStreamConfiguration^) 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());

      VideoStreamConfiguration *wrapperInstance = new VideoStreamConfiguration(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::Capture::VideoStreamConfiguration^>(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::Capture::VideoStreamConfiguration^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::VideoStreamConfiguration^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapVideoStreamConfiguration(winRtInstance));
    }


  



    static void InputPropertiesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::VideoStreamConfiguration^>(info.This()))
      {
        return;
      }

      VideoStreamConfiguration *wrapper = VideoStreamConfiguration::Unwrap<VideoStreamConfiguration>(info.This());

      try 
      {
        ::Windows::Media::MediaProperties::VideoEncodingProperties^ result = wrapper->_instance->InputProperties;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.MediaProperties", "VideoEncodingProperties", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void OutputPropertiesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::VideoStreamConfiguration^>(info.This()))
      {
        return;
      }

      VideoStreamConfiguration *wrapper = VideoStreamConfiguration::Unwrap<VideoStreamConfiguration>(info.This());

      try 
      {
        ::Windows::Media::MediaProperties::VideoEncodingProperties^ result = wrapper->_instance->OutputProperties;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.MediaProperties", "VideoEncodingProperties", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::VideoStreamConfiguration^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapVideoStreamConfiguration(::Windows::Media::Capture::VideoStreamConfiguration^ wintRtInstance);
    friend ::Windows::Media::Capture::VideoStreamConfiguration^ UnwrapVideoStreamConfiguration(Local<Value> value);
  };
  Persistent<FunctionTemplate> VideoStreamConfiguration::s_constructorTemplate;

  v8::Local<v8::Value> WrapVideoStreamConfiguration(::Windows::Media::Capture::VideoStreamConfiguration^ 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>(VideoStreamConfiguration::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::VideoStreamConfiguration^ UnwrapVideoStreamConfiguration(Local<Value> value)
  {
     return VideoStreamConfiguration::Unwrap<VideoStreamConfiguration>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitVideoStreamConfiguration(Local<Object> exports)
  {
    VideoStreamConfiguration::Init(exports);
  }

  class AppCaptureSettings : 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>("AppCaptureSettings").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isAppCaptureEnabled").ToLocalChecked(), IsAppCaptureEnabledGetter, IsAppCaptureEnabledSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("historicalBufferLengthUnit").ToLocalChecked(), HistoricalBufferLengthUnitGetter, HistoricalBufferLengthUnitSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("historicalBufferLength").ToLocalChecked(), HistoricalBufferLengthGetter, HistoricalBufferLengthSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isHistoricalCaptureOnWirelessDisplayAllowed").ToLocalChecked(), IsHistoricalCaptureOnWirelessDisplayAllowedGetter, IsHistoricalCaptureOnWirelessDisplayAllowedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customVideoEncodingWidth").ToLocalChecked(), CustomVideoEncodingWidthGetter, CustomVideoEncodingWidthSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customVideoEncodingHeight").ToLocalChecked(), CustomVideoEncodingHeightGetter, CustomVideoEncodingHeightSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customVideoEncodingBitrate").ToLocalChecked(), CustomVideoEncodingBitrateGetter, CustomVideoEncodingBitrateSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioEncodingBitrate").ToLocalChecked(), AudioEncodingBitrateGetter, AudioEncodingBitrateSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("appCaptureDestinationFolder").ToLocalChecked(), AppCaptureDestinationFolderGetter, AppCaptureDestinationFolderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isAudioCaptureEnabled").ToLocalChecked(), IsAudioCaptureEnabledGetter, IsAudioCaptureEnabledSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoEncodingResolutionMode").ToLocalChecked(), VideoEncodingResolutionModeGetter, VideoEncodingResolutionModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoEncodingBitrateMode").ToLocalChecked(), VideoEncodingBitrateModeGetter, VideoEncodingBitrateModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("screenshotDestinationFolder").ToLocalChecked(), ScreenshotDestinationFolderGetter, ScreenshotDestinationFolderSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maximumRecordLength").ToLocalChecked(), MaximumRecordLengthGetter, MaximumRecordLengthSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isHistoricalCaptureOnBatteryAllowed").ToLocalChecked(), IsHistoricalCaptureOnBatteryAllowedGetter, IsHistoricalCaptureOnBatteryAllowedSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isHistoricalCaptureEnabled").ToLocalChecked(), IsHistoricalCaptureEnabledGetter, IsHistoricalCaptureEnabledSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("hasHardwareEncoder").ToLocalChecked(), HasHardwareEncoderGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isCpuConstrained").ToLocalChecked(), IsCpuConstrainedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isDisabledByPolicy").ToLocalChecked(), IsDisabledByPolicyGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isMemoryConstrained").ToLocalChecked(), IsMemoryConstrainedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("alternateShortcutKeys").ToLocalChecked(), AlternateShortcutKeysGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isGpuConstrained").ToLocalChecked(), IsGpuConstrainedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isMicrophoneCaptureEnabled").ToLocalChecked(), IsMicrophoneCaptureEnabledGetter, IsMicrophoneCaptureEnabledSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("AppCaptureSettings").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    AppCaptureSettings(::Windows::Media::Capture::AppCaptureSettings^ 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::Capture::AppCaptureSettings^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::AppCaptureSettings^) 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());

      AppCaptureSettings *wrapperInstance = new AppCaptureSettings(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::Capture::AppCaptureSettings^>(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::Capture::AppCaptureSettings^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::AppCaptureSettings^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapAppCaptureSettings(winRtInstance));
    }


  



    static void IsAppCaptureEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsAppCaptureEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsAppCaptureEnabledSetter(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::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsAppCaptureEnabled = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void HistoricalBufferLengthUnitGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::AppCaptureHistoricalBufferLengthUnit result = wrapper->_instance->HistoricalBufferLengthUnit;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void HistoricalBufferLengthUnitSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::AppCaptureHistoricalBufferLengthUnit winRtValue = static_cast<::Windows::Media::Capture::AppCaptureHistoricalBufferLengthUnit>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->HistoricalBufferLengthUnit = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void HistoricalBufferLengthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->HistoricalBufferLength;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void HistoricalBufferLengthSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsUint32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->HistoricalBufferLength = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsHistoricalCaptureOnWirelessDisplayAllowedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsHistoricalCaptureOnWirelessDisplayAllowed;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsHistoricalCaptureOnWirelessDisplayAllowedSetter(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::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsHistoricalCaptureOnWirelessDisplayAllowed = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void CustomVideoEncodingWidthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->CustomVideoEncodingWidth;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CustomVideoEncodingWidthSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsUint32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->CustomVideoEncodingWidth = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void CustomVideoEncodingHeightGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->CustomVideoEncodingHeight;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CustomVideoEncodingHeightSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsUint32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->CustomVideoEncodingHeight = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void CustomVideoEncodingBitrateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->CustomVideoEncodingBitrate;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CustomVideoEncodingBitrateSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsUint32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->CustomVideoEncodingBitrate = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AudioEncodingBitrateGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->AudioEncodingBitrate;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AudioEncodingBitrateSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsUint32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->AudioEncodingBitrate = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AppCaptureDestinationFolderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        ::Windows::Storage::StorageFolder^ result = wrapper->_instance->AppCaptureDestinationFolder;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AppCaptureDestinationFolderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFolder^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Storage::StorageFolder^ winRtValue = dynamic_cast<::Windows::Storage::StorageFolder^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->AppCaptureDestinationFolder = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsAudioCaptureEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsAudioCaptureEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsAudioCaptureEnabledSetter(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::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsAudioCaptureEnabled = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void VideoEncodingResolutionModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::AppCaptureVideoEncodingResolutionMode result = wrapper->_instance->VideoEncodingResolutionMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoEncodingResolutionModeSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::AppCaptureVideoEncodingResolutionMode winRtValue = static_cast<::Windows::Media::Capture::AppCaptureVideoEncodingResolutionMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->VideoEncodingResolutionMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void VideoEncodingBitrateModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::AppCaptureVideoEncodingBitrateMode result = wrapper->_instance->VideoEncodingBitrateMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoEncodingBitrateModeSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Media::Capture::AppCaptureVideoEncodingBitrateMode winRtValue = static_cast<::Windows::Media::Capture::AppCaptureVideoEncodingBitrateMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->VideoEncodingBitrateMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ScreenshotDestinationFolderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        ::Windows::Storage::StorageFolder^ result = wrapper->_instance->ScreenshotDestinationFolder;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ScreenshotDestinationFolderSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFolder^>(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Storage::StorageFolder^ winRtValue = dynamic_cast<::Windows::Storage::StorageFolder^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->ScreenshotDestinationFolder = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void MaximumRecordLengthGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        ::Windows::Foundation::TimeSpan result = wrapper->_instance->MaximumRecordLength;
        info.GetReturnValue().Set(Nan::New<Number>(result.Duration/10000.0));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaximumRecordLengthSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsNumber())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        ::Windows::Foundation::TimeSpan winRtValue = NodeRT::Utils::TimeSpanFromMilli(Nan::To<int64_t>(value).FromMaybe(0));

        wrapper->_instance->MaximumRecordLength = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsHistoricalCaptureOnBatteryAllowedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsHistoricalCaptureOnBatteryAllowed;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsHistoricalCaptureOnBatteryAllowedSetter(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::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsHistoricalCaptureOnBatteryAllowed = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void IsHistoricalCaptureEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsHistoricalCaptureEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsHistoricalCaptureEnabledSetter(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::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsHistoricalCaptureEnabled = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void HasHardwareEncoderGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->HasHardwareEncoder;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsCpuConstrainedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsCpuConstrained;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsDisabledByPolicyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsDisabledByPolicy;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsMemoryConstrainedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsMemoryConstrained;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AlternateShortcutKeysGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        ::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ result = wrapper->_instance->AlternateShortcutKeys;
        info.GetReturnValue().Set(WrapAppCaptureAlternateShortcutKeys(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsGpuConstrainedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsGpuConstrained;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsMicrophoneCaptureEnabledGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsMicrophoneCaptureEnabled;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsMicrophoneCaptureEnabledSetter(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::Capture::AppCaptureSettings^>(info.This()))
      {
        return;
      }

      AppCaptureSettings *wrapper = AppCaptureSettings::Unwrap<AppCaptureSettings>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->IsMicrophoneCaptureEnabled = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Capture::AppCaptureSettings^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapAppCaptureSettings(::Windows::Media::Capture::AppCaptureSettings^ wintRtInstance);
    friend ::Windows::Media::Capture::AppCaptureSettings^ UnwrapAppCaptureSettings(Local<Value> value);
  };
  Persistent<FunctionTemplate> AppCaptureSettings::s_constructorTemplate;

  v8::Local<v8::Value> WrapAppCaptureSettings(::Windows::Media::Capture::AppCaptureSettings^ 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>(AppCaptureSettings::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::AppCaptureSettings^ UnwrapAppCaptureSettings(Local<Value> value)
  {
     return AppCaptureSettings::Unwrap<AppCaptureSettings>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAppCaptureSettings(Local<Object> exports)
  {
    AppCaptureSettings::Init(exports);
  }

  class AppCaptureAlternateShortcutKeys : 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>("AppCaptureAlternateShortcutKeys").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleRecordingKeyModifiers").ToLocalChecked(), ToggleRecordingKeyModifiersGetter, ToggleRecordingKeyModifiersSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleRecordingKey").ToLocalChecked(), ToggleRecordingKeyGetter, ToggleRecordingKeySetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleRecordingIndicatorKeyModifiers").ToLocalChecked(), ToggleRecordingIndicatorKeyModifiersGetter, ToggleRecordingIndicatorKeyModifiersSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleRecordingIndicatorKey").ToLocalChecked(), ToggleRecordingIndicatorKeyGetter, ToggleRecordingIndicatorKeySetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleGameBarKeyModifiers").ToLocalChecked(), ToggleGameBarKeyModifiersGetter, ToggleGameBarKeyModifiersSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleGameBarKey").ToLocalChecked(), ToggleGameBarKeyGetter, ToggleGameBarKeySetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("takeScreenshotKeyModifiers").ToLocalChecked(), TakeScreenshotKeyModifiersGetter, TakeScreenshotKeyModifiersSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("takeScreenshotKey").ToLocalChecked(), TakeScreenshotKeyGetter, TakeScreenshotKeySetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("saveHistoricalVideoKeyModifiers").ToLocalChecked(), SaveHistoricalVideoKeyModifiersGetter, SaveHistoricalVideoKeyModifiersSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("saveHistoricalVideoKey").ToLocalChecked(), SaveHistoricalVideoKeyGetter, SaveHistoricalVideoKeySetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleMicrophoneCaptureKeyModifiers").ToLocalChecked(), ToggleMicrophoneCaptureKeyModifiersGetter, ToggleMicrophoneCaptureKeyModifiersSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleMicrophoneCaptureKey").ToLocalChecked(), ToggleMicrophoneCaptureKeyGetter, ToggleMicrophoneCaptureKeySetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("AppCaptureAlternateShortcutKeys").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    AppCaptureAlternateShortcutKeys(::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ 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::Capture::AppCaptureAlternateShortcutKeys^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^) 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());

      AppCaptureAlternateShortcutKeys *wrapperInstance = new AppCaptureAlternateShortcutKeys(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::Capture::AppCaptureAlternateShortcutKeys^>(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::Capture::AppCaptureAlternateShortcutKeys^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapAppCaptureAlternateShortcutKeys(winRtInstance));
    }


  



    static void ToggleRecordingKeyModifiersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKeyModifiers result = wrapper->_instance->ToggleRecordingKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleRecordingKeyModifiersSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKeyModifiers winRtValue = static_cast<::Windows::System::VirtualKeyModifiers>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleRecordingKeyModifiers = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ToggleRecordingKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKey result = wrapper->_instance->ToggleRecordingKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleRecordingKeySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKey winRtValue = static_cast<::Windows::System::VirtualKey>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleRecordingKey = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ToggleRecordingIndicatorKeyModifiersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKeyModifiers result = wrapper->_instance->ToggleRecordingIndicatorKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleRecordingIndicatorKeyModifiersSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKeyModifiers winRtValue = static_cast<::Windows::System::VirtualKeyModifiers>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleRecordingIndicatorKeyModifiers = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ToggleRecordingIndicatorKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKey result = wrapper->_instance->ToggleRecordingIndicatorKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleRecordingIndicatorKeySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKey winRtValue = static_cast<::Windows::System::VirtualKey>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleRecordingIndicatorKey = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ToggleGameBarKeyModifiersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKeyModifiers result = wrapper->_instance->ToggleGameBarKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleGameBarKeyModifiersSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKeyModifiers winRtValue = static_cast<::Windows::System::VirtualKeyModifiers>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleGameBarKeyModifiers = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ToggleGameBarKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKey result = wrapper->_instance->ToggleGameBarKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleGameBarKeySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKey winRtValue = static_cast<::Windows::System::VirtualKey>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleGameBarKey = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void TakeScreenshotKeyModifiersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKeyModifiers result = wrapper->_instance->TakeScreenshotKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TakeScreenshotKeyModifiersSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKeyModifiers winRtValue = static_cast<::Windows::System::VirtualKeyModifiers>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->TakeScreenshotKeyModifiers = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void TakeScreenshotKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKey result = wrapper->_instance->TakeScreenshotKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void TakeScreenshotKeySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKey winRtValue = static_cast<::Windows::System::VirtualKey>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->TakeScreenshotKey = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void SaveHistoricalVideoKeyModifiersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKeyModifiers result = wrapper->_instance->SaveHistoricalVideoKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SaveHistoricalVideoKeyModifiersSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKeyModifiers winRtValue = static_cast<::Windows::System::VirtualKeyModifiers>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SaveHistoricalVideoKeyModifiers = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void SaveHistoricalVideoKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKey result = wrapper->_instance->SaveHistoricalVideoKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SaveHistoricalVideoKeySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKey winRtValue = static_cast<::Windows::System::VirtualKey>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SaveHistoricalVideoKey = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ToggleMicrophoneCaptureKeyModifiersGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKeyModifiers result = wrapper->_instance->ToggleMicrophoneCaptureKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleMicrophoneCaptureKeyModifiersSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKeyModifiers winRtValue = static_cast<::Windows::System::VirtualKeyModifiers>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleMicrophoneCaptureKeyModifiers = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ToggleMicrophoneCaptureKeyGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        ::Windows::System::VirtualKey result = wrapper->_instance->ToggleMicrophoneCaptureKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ToggleMicrophoneCaptureKeySetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^>(info.This()))
      {
        return;
      }

      AppCaptureAlternateShortcutKeys *wrapper = AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(info.This());

      try 
      {
        
        ::Windows::System::VirtualKey winRtValue = static_cast<::Windows::System::VirtualKey>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ToggleMicrophoneCaptureKey = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapAppCaptureAlternateShortcutKeys(::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ wintRtInstance);
    friend ::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ UnwrapAppCaptureAlternateShortcutKeys(Local<Value> value);
  };
  Persistent<FunctionTemplate> AppCaptureAlternateShortcutKeys::s_constructorTemplate;

  v8::Local<v8::Value> WrapAppCaptureAlternateShortcutKeys(::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ 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>(AppCaptureAlternateShortcutKeys::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::AppCaptureAlternateShortcutKeys^ UnwrapAppCaptureAlternateShortcutKeys(Local<Value> value)
  {
     return AppCaptureAlternateShortcutKeys::Unwrap<AppCaptureAlternateShortcutKeys>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAppCaptureAlternateShortcutKeys(Local<Object> exports)
  {
    AppCaptureAlternateShortcutKeys::Init(exports);
  }

  class AppCaptureManager : 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>("AppCaptureManager").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "getCurrentSettings", GetCurrentSettings);
      Nan::SetMethod(constructor, "applySettings", ApplySettings);

      Nan::Set(exports, Nan::New<String>("AppCaptureManager").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    AppCaptureManager(::Windows::Media::Capture::AppCaptureManager^ 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::Capture::AppCaptureManager^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureManager^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::AppCaptureManager^) 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());

      AppCaptureManager *wrapperInstance = new AppCaptureManager(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::Capture::AppCaptureManager^>(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::Capture::AppCaptureManager^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::AppCaptureManager^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapAppCaptureManager(winRtInstance));
    }


  


    static void GetCurrentSettings(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Capture::AppCaptureSettings^ result;
          result = ::Windows::Media::Capture::AppCaptureManager::GetCurrentSettings();
          info.GetReturnValue().Set(WrapAppCaptureSettings(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 ApplySettings(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::AppCaptureSettings^>(info[0]))
      {
        try
        {
          ::Windows::Media::Capture::AppCaptureSettings^ arg0 = UnwrapAppCaptureSettings(info[0]);
          
          ::Windows::Media::Capture::AppCaptureManager::ApplySettings(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::Capture::AppCaptureManager^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapAppCaptureManager(::Windows::Media::Capture::AppCaptureManager^ wintRtInstance);
    friend ::Windows::Media::Capture::AppCaptureManager^ UnwrapAppCaptureManager(Local<Value> value);
  };
  Persistent<FunctionTemplate> AppCaptureManager::s_constructorTemplate;

  v8::Local<v8::Value> WrapAppCaptureManager(::Windows::Media::Capture::AppCaptureManager^ 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>(AppCaptureManager::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::AppCaptureManager^ UnwrapAppCaptureManager(Local<Value> value)
  {
     return AppCaptureManager::Unwrap<AppCaptureManager>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitAppCaptureManager(Local<Object> exports)
  {
    AppCaptureManager::Init(exports);
  }

  class CameraOptionsUI : 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>("CameraOptionsUI").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "show", Show);

      Nan::Set(exports, Nan::New<String>("CameraOptionsUI").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    CameraOptionsUI(::Windows::Media::Capture::CameraOptionsUI^ 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::Capture::CameraOptionsUI^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::CameraOptionsUI^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::CameraOptionsUI^) 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());

      CameraOptionsUI *wrapperInstance = new CameraOptionsUI(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::Capture::CameraOptionsUI^>(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::Capture::CameraOptionsUI^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::CameraOptionsUI^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapCameraOptionsUI(winRtInstance));
    }


  


    static void Show(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapture^>(info[0]))
      {
        try
        {
          ::Windows::Media::Capture::MediaCapture^ arg0 = UnwrapMediaCapture(info[0]);
          
          ::Windows::Media::Capture::CameraOptionsUI::Show(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::Capture::CameraOptionsUI^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapCameraOptionsUI(::Windows::Media::Capture::CameraOptionsUI^ wintRtInstance);
    friend ::Windows::Media::Capture::CameraOptionsUI^ UnwrapCameraOptionsUI(Local<Value> value);
  };
  Persistent<FunctionTemplate> CameraOptionsUI::s_constructorTemplate;

  v8::Local<v8::Value> WrapCameraOptionsUI(::Windows::Media::Capture::CameraOptionsUI^ 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>(CameraOptionsUI::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::CameraOptionsUI^ UnwrapCameraOptionsUI(Local<Value> value)
  {
     return CameraOptionsUI::Unwrap<CameraOptionsUI>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitCameraOptionsUI(Local<Object> exports)
  {
    CameraOptionsUI::Init(exports);
  }

  class ScreenCapture : 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>("ScreenCapture").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                        
      Nan::SetPrototypeMethod(localRef,"addListener", AddListener);
      Nan::SetPrototypeMethod(localRef,"on", AddListener);
      Nan::SetPrototypeMethod(localRef,"removeListener", RemoveListener);
      Nan::SetPrototypeMethod(localRef, "off", RemoveListener);
            
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioSource").ToLocalChecked(), AudioSourceGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isAudioSuspended").ToLocalChecked(), IsAudioSuspendedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isVideoSuspended").ToLocalChecked(), IsVideoSuspendedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoSource").ToLocalChecked(), VideoSourceGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "getForCurrentView", GetForCurrentView);

      Nan::Set(exports, Nan::New<String>("ScreenCapture").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ScreenCapture(::Windows::Media::Capture::ScreenCapture^ 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::Capture::ScreenCapture^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::ScreenCapture^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::ScreenCapture^) 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());

      ScreenCapture *wrapperInstance = new ScreenCapture(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::Capture::ScreenCapture^>(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::Capture::ScreenCapture^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::ScreenCapture^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapScreenCapture(winRtInstance));
    }


  


    static void GetForCurrentView(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 0)
      {
        try
        {
          ::Windows::Media::Capture::ScreenCapture^ result;
          result = ::Windows::Media::Capture::ScreenCapture::GetForCurrentView();
          info.GetReturnValue().Set(WrapScreenCapture(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 AudioSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::ScreenCapture^>(info.This()))
      {
        return;
      }

      ScreenCapture *wrapper = ScreenCapture::Unwrap<ScreenCapture>(info.This());

      try 
      {
        ::Windows::Media::Core::IMediaSource^ result = wrapper->_instance->AudioSource;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Core", "IMediaSource", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsAudioSuspendedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::ScreenCapture^>(info.This()))
      {
        return;
      }

      ScreenCapture *wrapper = ScreenCapture::Unwrap<ScreenCapture>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsAudioSuspended;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsVideoSuspendedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::ScreenCapture^>(info.This()))
      {
        return;
      }

      ScreenCapture *wrapper = ScreenCapture::Unwrap<ScreenCapture>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsVideoSuspended;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void VideoSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::ScreenCapture^>(info.This()))
      {
        return;
      }

      ScreenCapture *wrapper = ScreenCapture::Unwrap<ScreenCapture>(info.This());

      try 
      {
        ::Windows::Media::Core::IMediaSource^ result = wrapper->_instance->VideoSource;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Core", "IMediaSource", result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        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"sourceSuspensionChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::ScreenCapture^>(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;
        }
        ScreenCapture *wrapper = ScreenCapture::Unwrap<ScreenCapture>(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->SourceSuspensionChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Media::Capture::ScreenCapture^, ::Windows::Media::Capture::SourceSuspensionChangedEventArgs^>(
            [callbackObjPtr](::Windows::Media::Capture::ScreenCapture^ arg0, ::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
           	    HandleScope scope;
                TryCatch tryCatch;
              
                Local<Value> error;

                Local<Value> wrappedArg0 = WrapScreenCapture(arg0);
                Local<Value> wrappedArg1 = WrapSourceSuspensionChangedEventArgs(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"sourceSuspensionChanged", 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"sourceSuspensionChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::ScreenCapture^>(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;
          }
          ScreenCapture *wrapper = ScreenCapture::Unwrap<ScreenCapture>(info.This());
          wrapper->_instance->SourceSuspensionChanged::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::Capture::ScreenCapture^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapScreenCapture(::Windows::Media::Capture::ScreenCapture^ wintRtInstance);
    friend ::Windows::Media::Capture::ScreenCapture^ UnwrapScreenCapture(Local<Value> value);
  };
  Persistent<FunctionTemplate> ScreenCapture::s_constructorTemplate;

  v8::Local<v8::Value> WrapScreenCapture(::Windows::Media::Capture::ScreenCapture^ 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>(ScreenCapture::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::ScreenCapture^ UnwrapScreenCapture(Local<Value> value)
  {
     return ScreenCapture::Unwrap<ScreenCapture>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitScreenCapture(Local<Object> exports)
  {
    ScreenCapture::Init(exports);
  }

  class SourceSuspensionChangedEventArgs : 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>("SourceSuspensionChangedEventArgs").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isAudioSuspended").ToLocalChecked(), IsAudioSuspendedGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isVideoSuspended").ToLocalChecked(), IsVideoSuspendedGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("SourceSuspensionChangedEventArgs").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    SourceSuspensionChangedEventArgs(::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ 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::Capture::SourceSuspensionChangedEventArgs^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::SourceSuspensionChangedEventArgs^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Media::Capture::SourceSuspensionChangedEventArgs^) 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());

      SourceSuspensionChangedEventArgs *wrapperInstance = new SourceSuspensionChangedEventArgs(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::Capture::SourceSuspensionChangedEventArgs^>(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::Capture::SourceSuspensionChangedEventArgs^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Media::Capture::SourceSuspensionChangedEventArgs^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapSourceSuspensionChangedEventArgs(winRtInstance));
    }


  



    static void IsAudioSuspendedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::SourceSuspensionChangedEventArgs^>(info.This()))
      {
        return;
      }

      SourceSuspensionChangedEventArgs *wrapper = SourceSuspensionChangedEventArgs::Unwrap<SourceSuspensionChangedEventArgs>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsAudioSuspended;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void IsVideoSuspendedGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::SourceSuspensionChangedEventArgs^>(info.This()))
      {
        return;
      }

      SourceSuspensionChangedEventArgs *wrapper = SourceSuspensionChangedEventArgs::Unwrap<SourceSuspensionChangedEventArgs>(info.This());

      try 
      {
        bool result = wrapper->_instance->IsVideoSuspended;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapSourceSuspensionChangedEventArgs(::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ wintRtInstance);
    friend ::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ UnwrapSourceSuspensionChangedEventArgs(Local<Value> value);
  };
  Persistent<FunctionTemplate> SourceSuspensionChangedEventArgs::s_constructorTemplate;

  v8::Local<v8::Value> WrapSourceSuspensionChangedEventArgs(::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ 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>(SourceSuspensionChangedEventArgs::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::SourceSuspensionChangedEventArgs^ UnwrapSourceSuspensionChangedEventArgs(Local<Value> value)
  {
     return SourceSuspensionChangedEventArgs::Unwrap<SourceSuspensionChangedEventArgs>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitSourceSuspensionChangedEventArgs(Local<Object> exports)
  {
    SourceSuspensionChangedEventArgs::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::Capture::InitCameraCaptureUIModeEnum(target);
  NodeRT::Windows::Media::Capture::InitCameraCaptureUIPhotoFormatEnum(target);
  NodeRT::Windows::Media::Capture::InitCameraCaptureUIVideoFormatEnum(target);
  NodeRT::Windows::Media::Capture::InitCameraCaptureUIMaxVideoResolutionEnum(target);
  NodeRT::Windows::Media::Capture::InitCameraCaptureUIMaxPhotoResolutionEnum(target);
  NodeRT::Windows::Media::Capture::InitMediaCategoryEnum(target);
  NodeRT::Windows::Media::Capture::InitMediaStreamTypeEnum(target);
  NodeRT::Windows::Media::Capture::InitStreamingCaptureModeEnum(target);
  NodeRT::Windows::Media::Capture::InitVideoRotationEnum(target);
  NodeRT::Windows::Media::Capture::InitPhotoCaptureSourceEnum(target);
  NodeRT::Windows::Media::Capture::InitVideoDeviceCharacteristicEnum(target);
  NodeRT::Windows::Media::Capture::InitPowerlineFrequencyEnum(target);
  NodeRT::Windows::Media::Capture::InitMediaCaptureThermalStatusEnum(target);
  NodeRT::Windows::Media::Capture::InitKnownVideoProfileEnum(target);
  NodeRT::Windows::Media::Capture::InitAppCaptureVideoEncodingBitrateModeEnum(target);
  NodeRT::Windows::Media::Capture::InitAppCaptureVideoEncodingResolutionModeEnum(target);
  NodeRT::Windows::Media::Capture::InitAppCaptureHistoricalBufferLengthUnitEnum(target);
  NodeRT::Windows::Media::Capture::InitCameraCaptureUIPhotoCaptureSettings(target);
  NodeRT::Windows::Media::Capture::InitCameraCaptureUIVideoCaptureSettings(target);
  NodeRT::Windows::Media::Capture::InitCameraCaptureUI(target);
  NodeRT::Windows::Media::Capture::InitAppCapture(target);
  NodeRT::Windows::Media::Capture::InitMediaCaptureFailedEventArgs(target);
  NodeRT::Windows::Media::Capture::InitMediaCapture(target);
  NodeRT::Windows::Media::Capture::InitMediaCaptureVideoProfileMediaDescription(target);
  NodeRT::Windows::Media::Capture::InitMediaCaptureVideoProfile(target);
  NodeRT::Windows::Media::Capture::InitMediaCaptureInitializationSettings(target);
  NodeRT::Windows::Media::Capture::InitMediaCaptureSettings(target);
  NodeRT::Windows::Media::Capture::InitLowLagMediaRecording(target);
  NodeRT::Windows::Media::Capture::InitLowLagPhotoCapture(target);
  NodeRT::Windows::Media::Capture::InitLowLagPhotoSequenceCapture(target);
  NodeRT::Windows::Media::Capture::InitMediaCaptureFocusChangedEventArgs(target);
  NodeRT::Windows::Media::Capture::InitPhotoConfirmationCapturedEventArgs(target);
  NodeRT::Windows::Media::Capture::InitAdvancedPhotoCapture(target);
  NodeRT::Windows::Media::Capture::InitCapturedPhoto(target);
  NodeRT::Windows::Media::Capture::InitAdvancedCapturedPhoto(target);
  NodeRT::Windows::Media::Capture::InitOptionalReferencePhotoCapturedEventArgs(target);
  NodeRT::Windows::Media::Capture::InitCapturedFrame(target);
  NodeRT::Windows::Media::Capture::InitPhotoCapturedEventArgs(target);
  NodeRT::Windows::Media::Capture::InitCapturedFrameControlValues(target);
  NodeRT::Windows::Media::Capture::InitVideoStreamConfiguration(target);
  NodeRT::Windows::Media::Capture::InitAppCaptureSettings(target);
  NodeRT::Windows::Media::Capture::InitAppCaptureAlternateShortcutKeys(target);
  NodeRT::Windows::Media::Capture::InitAppCaptureManager(target);
  NodeRT::Windows::Media::Capture::InitCameraOptionsUI(target);
  NodeRT::Windows::Media::Capture::InitScreenCapture(target);
  NodeRT::Windows::Media::Capture::InitSourceSuspensionChangedEventArgs(target);

  NodeRT::Utils::RegisterNameSpace("Windows.Media.Capture", target);
}


NODE_MODULE(binding, init)