// Copyright (c) The NodeRT Contributors
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may
// not use this file except in compliance with the License. You may obtain a
// copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED ON AN  *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
// MERCHANTABLITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions
// and limitations under the License.

// TODO: Verify that this is is still needed..
#define NTDDI_VERSION 0x06010000

#include <v8.h>
#include "nan.h"
#include <string>
#include <ppltasks.h>
#include "CollectionsConverter.h"
#include "CollectionsWrap.h"
#include "node-async.h"
#include "NodeRtUtils.h"
#include "OpaqueWrapper.h"
#include "WrapperBase.h"

#using <Windows.WinMD>

// this undefs fixes the issues of compiling Windows.Data.Json, Windows.Storag.FileProperties, and Windows.Stroage.Search
// Some of the node header files brings windows definitions with the same names as some of the WinRT methods
#undef DocumentProperties
#undef GetObject
#undef CreateEvent
#undef FindText
#undef SendMessage

const char* REGISTRATION_TOKEN_MAP_PROPERTY_NAME = "__registrationTokenMap__";

using v8::Array;
using v8::String;
using v8::Value;
using v8::Boolean;
using v8::Integer;
using v8::FunctionTemplate;
using v8::Object;
using v8::Local;
using v8::Function;
using v8::Date;
using v8::Number;
using v8::PropertyAttribute;
using v8::Primitive;
using Nan::HandleScope;
using Nan::Persistent;
using Nan::Undefined;
using Nan::True;
using Nan::False;
using Nan::Null;
using Nan::MaybeLocal;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::TryCatch;
using namespace concurrency;

namespace NodeRT { namespace Windows { namespace Media { namespace Capture { 
  v8::Local<v8::Value> WrapAppCapture(::Windows::Media::Capture::AppCapture^ wintRtInstance);
  ::Windows::Media::Capture::AppCapture^ UnwrapAppCapture(Local<Value> value);
  
  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> 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> WrapMediaCapturePauseResult(::Windows::Media::Capture::MediaCapturePauseResult^ wintRtInstance);
  ::Windows::Media::Capture::MediaCapturePauseResult^ UnwrapMediaCapturePauseResult(Local<Value> value);
  
  v8::Local<v8::Value> WrapMediaCaptureStopResult(::Windows::Media::Capture::MediaCaptureStopResult^ wintRtInstance);
  ::Windows::Media::Capture::MediaCaptureStopResult^ UnwrapMediaCaptureStopResult(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)));
    Nan::Set(enumObject, Nan::New<String>("auto").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::PowerlineFrequency::Auto)));
  }

  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 InitMediaCaptureMemoryPreferenceEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("MediaCaptureMemoryPreference").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("auto").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCaptureMemoryPreference::Auto)));
    Nan::Set(enumObject, Nan::New<String>("cpu").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCaptureMemoryPreference::Cpu)));
  }

  static void InitMediaCaptureSharingModeEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("MediaCaptureSharingMode").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("exclusiveControl").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCaptureSharingMode::ExclusiveControl)));
    Nan::Set(enumObject, Nan::New<String>("sharedReadOnly").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::MediaCaptureSharingMode::SharedReadOnly)));
  }

  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 InitAppCaptureVideoEncodingFrameRateModeEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("AppCaptureVideoEncodingFrameRateMode").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("standard").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingFrameRateMode::Standard)));
    Nan::Set(enumObject, Nan::New<String>("high").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Media::Capture::AppCaptureVideoEncodingFrameRateMode::High)));
  }

  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);
  }
  static bool IsBitmapSizeJsObject(Local<Value> value) {
    if (!value->IsObject()) {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    symbol = Nan::New<String>("width").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false)) {
      if (!Nan::Get(obj,symbol).ToLocalChecked()->IsUint32()) {
        return false;
      }
    }
    
    symbol = Nan::New<String>("height").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false)) {
      if (!Nan::Get(obj,symbol).ToLocalChecked()->IsUint32()) {
        return false;
      }
    }
    
    return true;
  }

  ::Windows::Graphics::Imaging::BitmapSize BitmapSizeFromJsObject(Local<Value> value) {
    HandleScope scope;
    ::Windows::Graphics::Imaging::BitmapSize 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>("width").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false)) {
      returnValue.Width = static_cast<unsigned int>(Nan::To<uint32_t>(Nan::Get(obj,symbol).ToLocalChecked()).FromMaybe(0));
    }
    
    symbol = Nan::New<String>("height").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false)) {
      returnValue.Height = static_cast<unsigned int>(Nan::To<uint32_t>(Nan::Get(obj,symbol).ToLocalChecked()).FromMaybe(0));
    }
    
    return returnValue;
  }

  Local<Value> BitmapSizeToJsObject(::Windows::Graphics::Imaging::BitmapSize value) {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();

    Nan::Set(obj, Nan::New<String>("width").ToLocalChecked(), Nan::New<Integer>(value.Width));
    Nan::Set(obj, Nan::New<String>("height").ToLocalChecked(), Nan::New<Integer>(value.Height));

    return scope.Escape(obj);
  }
  static bool IsRectJsObject(Local<Value> value) {
    if (!value->IsObject()) {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    return true;
  }

  ::Windows::Foundation::Rect RectFromJsObject(Local<Value> value) {
    HandleScope scope;
    ::Windows::Foundation::Rect 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> RectToJsObject(::Windows::Foundation::Rect value) {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();


    return scope.Escape(obj);
  }

  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(v8::Isolate::GetCurrent(), 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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapAppCapture(arg0);
                  wrappedArg1 = CreateOpaqueWrapper(arg1);


                  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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), info[0]);
      auto str = *eventName;

      if ((!NodeRT::Utils::CaseInsenstiveEquals(L"capturingChanged", str))) {
        Nan::ThrowError(Nan::Error(String::Concat(v8::Isolate::GetCurrent(), 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 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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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 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, "removeEffectAsync", RemoveEffectAsync);
            Nan::SetPrototypeMethod(localRef, "pauseRecordWithResultAsync", PauseRecordWithResultAsync);
            Nan::SetPrototypeMethod(localRef, "stopRecordWithResultAsync", StopRecordWithResultAsync);
            Nan::SetPrototypeMethod(localRef, "createFrameReaderAsync", CreateFrameReaderAsync);
            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);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frameSources").ToLocalChecked(), FrameSourcesGetter);

        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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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 RemoveEffectAsync(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
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::IMediaExtension^>(info[0]))
      {
        try
        {
          ::Windows::Media::IMediaExtension^ arg0 = dynamic_cast<::Windows::Media::IMediaExtension^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->RemoveEffectAsync(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 PauseRecordWithResultAsync(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::MediaCapturePauseResult^>^ 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->PauseRecordWithResultAsync(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::MediaCapturePauseResult^> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = WrapMediaCapturePauseResult(result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        } catch (Platform::Exception^ exception) {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }
    static void StopRecordWithResultAsync(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::MediaCaptureStopResult^>^ op;


      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StopRecordWithResultAsync();
        }
        catch (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::MediaCaptureStopResult^> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = WrapMediaCaptureStopResult(result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        } catch (Platform::Exception^ exception) {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }
    static void CreateFrameReaderAsync(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::Frames::MediaFrameReader^>^ op;


      if (info.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::Frames::MediaFrameSource^>(info[0]))
      {
        try
        {
          ::Windows::Media::Capture::Frames::MediaFrameSource^ arg0 = dynamic_cast<::Windows::Media::Capture::Frames::MediaFrameSource^>(NodeRT::Utils::GetObjectInstance(info[0]));
          
          op = wrapper->_instance->CreateFrameReaderAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 3
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::Frames::MediaFrameSource^>(info[0])
        && info[1]->IsString())
      {
        try
        {
          ::Windows::Media::Capture::Frames::MediaFrameSource^ arg0 = dynamic_cast<::Windows::Media::Capture::Frames::MediaFrameSource^>(NodeRT::Utils::GetObjectInstance(info[0]));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          
          op = wrapper->_instance->CreateFrameReaderAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else if (info.Length() == 4
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::Frames::MediaFrameSource^>(info[0])
        && info[1]->IsString()
        && IsBitmapSizeJsObject(info[2]))
      {
        try
        {
          ::Windows::Media::Capture::Frames::MediaFrameSource^ arg0 = dynamic_cast<::Windows::Media::Capture::Frames::MediaFrameSource^>(NodeRT::Utils::GetObjectInstance(info[0]));
          Platform::String^ arg1 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), info[1])));
          ::Windows::Graphics::Imaging::BitmapSize arg2 = BitmapSizeFromJsObject(info[2]);
          
          op = wrapper->_instance->CreateFrameReaderAsync(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::Frames::MediaFrameReader^> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Capture.Frames", "MediaFrameReader", result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        } catch (Platform::Exception^ exception) {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }
    static void 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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), 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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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(v8::Isolate::GetCurrent(), 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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), 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 FrameSourcesGetter(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::Foundation::Collections::IMapView<::Platform::String^, ::Windows::Media::Capture::Frames::MediaFrameSource^>^ result = wrapper->_instance->FrameSources;
        info.GetReturnValue().Set(NodeRT::Collections::MapViewWrapper<::Platform::String^,::Windows::Media::Capture::Frames::MediaFrameSource^>::CreateMapViewWrapper(result, 
            [](::Platform::String^ val) -> Local<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Local<Value> value) -> bool {
              return value->IsString();
            },
            [](Local<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(v8::Isolate::GetCurrent(), value)));
            },
            [](::Windows::Media::Capture::Frames::MediaFrameSource^ val) -> Local<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Capture.Frames", "MediaFrameSource", val);
            }
          ));
        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(v8::Isolate::GetCurrent(), 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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapMediaCapture(arg0);
                  wrappedArg1 = WrapMediaCaptureFailedEventArgs(arg1);


                  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;


                Local<Value> wrappedArg0;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapMediaCapture(arg0);


                  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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapMediaCapture(arg0);
                  wrappedArg1 = WrapMediaCaptureFocusChangedEventArgs(arg1);


                  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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapMediaCapture(arg0);
                  wrappedArg1 = WrapPhotoConfirmationCapturedEventArgs(arg1);


                  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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapMediaCapture(arg0);
                  wrappedArg1 = CreateOpaqueWrapper(arg1);


                  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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapMediaCapture(arg0);
                  wrappedArg1 = CreateOpaqueWrapper(arg1);


                  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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), 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>("audioDeviceId").ToLocalChecked(), AudioDeviceIdGetter, AudioDeviceIdSetter);
            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>("mediaCategory").ToLocalChecked(), MediaCategoryGetter, MediaCategorySetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioProcessing").ToLocalChecked(), AudioProcessingGetter, AudioProcessingSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoSource").ToLocalChecked(), VideoSourceGetter, VideoSourceSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("audioSource").ToLocalChecked(), AudioSourceGetter, AudioSourceSetter);
            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);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("sharingMode").ToLocalChecked(), SharingModeGetter, SharingModeSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("sourceGroup").ToLocalChecked(), SourceGroupGetter, SourceGroupSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("memoryPreference").ToLocalChecked(), MemoryPreferenceGetter, MemoryPreferenceSetter);

        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 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(v8::Isolate::GetCurrent(), value)));

        wrapper->_instance->AudioDeviceId = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    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(v8::Isolate::GetCurrent(), 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 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 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 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 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);
      }
    }
      
    static void SharingModeGetter(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::MediaCaptureSharingMode result = wrapper->_instance->SharingMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SharingModeSetter(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::MediaCaptureSharingMode winRtValue = static_cast<::Windows::Media::Capture::MediaCaptureSharingMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->SharingMode = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void SourceGroupGetter(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::Frames::MediaFrameSourceGroup^ result = wrapper->_instance->SourceGroup;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media.Capture.Frames", "MediaFrameSourceGroup", result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SourceGroupSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::Frames::MediaFrameSourceGroup^>(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::Frames::MediaFrameSourceGroup^ winRtValue = dynamic_cast<::Windows::Media::Capture::Frames::MediaFrameSourceGroup^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->SourceGroup = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void MemoryPreferenceGetter(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::MediaCaptureMemoryPreference result = wrapper->_instance->MemoryPreference;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void MemoryPreferenceSetter(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::MediaCaptureMemoryPreference winRtValue = static_cast<::Windows::Media::Capture::MediaCaptureMemoryPreference>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->MemoryPreference = 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);
            Nan::SetPrototypeMethod(localRef, "pauseWithResultAsync", PauseWithResultAsync);
            Nan::SetPrototypeMethod(localRef, "stopWithResultAsync", StopWithResultAsync);
          



        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);
          });
        }
      });
    }
    static void PauseWithResultAsync(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::IAsyncOperation<::Windows::Media::Capture::MediaCapturePauseResult^>^ 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->PauseWithResultAsync(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::MediaCapturePauseResult^> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = WrapMediaCapturePauseResult(result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        } catch (Platform::Exception^ exception) {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }
    static void StopWithResultAsync(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::IAsyncOperation<::Windows::Media::Capture::MediaCaptureStopResult^>^ op;


      if (info.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->StopWithResultAsync();
        }
        catch (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::MediaCaptureStopResult^> t) {
        try {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = WrapMediaCaptureStopResult(result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        } catch (Platform::Exception^ exception) {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }






    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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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(v8::Isolate::GetCurrent(), 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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapLowLagPhotoSequenceCapture(arg0);
                  wrappedArg1 = WrapPhotoCapturedEventArgs(arg1);


                  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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), info[0]);
      auto str = *eventName;

      if ((!NodeRT::Utils::CaseInsenstiveEquals(L"photoCaptured", str))) {
        Nan::ThrowError(Nan::Error(String::Concat(v8::Isolate::GetCurrent(), 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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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(v8::Isolate::GetCurrent(), 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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapAdvancedPhotoCapture(arg0);
                  wrappedArg1 = CreateOpaqueWrapper(arg1);


                  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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapAdvancedPhotoCapture(arg0);
                  wrappedArg1 = WrapOptionalReferencePhotoCapturedEventArgs(arg1);


                  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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), info[0]);
      auto str = *eventName;

      if ((!NodeRT::Utils::CaseInsenstiveEquals(L"allPhotosCaptured", str)) &&(!NodeRT::Utils::CaseInsenstiveEquals(L"optionalReferencePhotoCaptured", str))) {
        Nan::ThrowError(Nan::Error(String::Concat(v8::Isolate::GetCurrent(), 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 MediaCapturePauseResult : 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>("MediaCapturePauseResult").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "close", Close);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("lastFrame").ToLocalChecked(), LastFrameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("recordDuration").ToLocalChecked(), RecordDurationGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("MediaCapturePauseResult").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      MediaCapturePauseResult(::Windows::Media::Capture::MediaCapturePauseResult^ 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::MediaCapturePauseResult^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapturePauseResult^>(info[0])) {
        try {
          winRtInstance = (::Windows::Media::Capture::MediaCapturePauseResult^) 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());

      MediaCapturePauseResult *wrapperInstance = new MediaCapturePauseResult(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::MediaCapturePauseResult^>(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::MediaCapturePauseResult^ winRtInstance;
      try {
        winRtInstance = (::Windows::Media::Capture::MediaCapturePauseResult^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapMediaCapturePauseResult(winRtInstance));
    }



    static void Close(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapturePauseResult^>(info.This())) {
        return;
      }

      MediaCapturePauseResult *wrapper = MediaCapturePauseResult::Unwrap<MediaCapturePauseResult>(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 LastFrameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapturePauseResult^>(info.This())) {
        return;
      }

      MediaCapturePauseResult *wrapper = MediaCapturePauseResult::Unwrap<MediaCapturePauseResult>(info.This());

      try  {
        ::Windows::Media::VideoFrame^ result = wrapper->_instance->LastFrame;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media", "VideoFrame", result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void RecordDurationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCapturePauseResult^>(info.This())) {
        return;
      }

      MediaCapturePauseResult *wrapper = MediaCapturePauseResult::Unwrap<MediaCapturePauseResult>(info.This());

      try  {
        ::Windows::Foundation::TimeSpan result = wrapper->_instance->RecordDuration;
        info.GetReturnValue().Set(Nan::New<Number>(result.Duration/10000.0));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Media::Capture::MediaCapturePauseResult^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapMediaCapturePauseResult(::Windows::Media::Capture::MediaCapturePauseResult^ wintRtInstance);
      friend ::Windows::Media::Capture::MediaCapturePauseResult^ UnwrapMediaCapturePauseResult(Local<Value> value);
  };

  Persistent<FunctionTemplate> MediaCapturePauseResult::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCapturePauseResult(::Windows::Media::Capture::MediaCapturePauseResult^ 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>(MediaCapturePauseResult::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCapturePauseResult^ UnwrapMediaCapturePauseResult(Local<Value> value) {
     return MediaCapturePauseResult::Unwrap<MediaCapturePauseResult>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCapturePauseResult(Local<Object> exports) {
    MediaCapturePauseResult::Init(exports);
  }

  class MediaCaptureStopResult : 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>("MediaCaptureStopResult").ToLocalChecked());
        localRef->InstanceTemplate()->SetInternalFieldCount(1);


          
            Nan::SetPrototypeMethod(localRef, "close", Close);
          



          
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("lastFrame").ToLocalChecked(), LastFrameGetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("recordDuration").ToLocalChecked(), RecordDurationGetter);

        Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
        Nan::SetMethod(constructor, "castFrom", CastFrom);



        Nan::Set(exports, Nan::New<String>("MediaCaptureStopResult").ToLocalChecked(), constructor);
      }

      virtual ::Platform::Object^ GetObjectInstance() const override {
        return _instance;
      }

    private:

      MediaCaptureStopResult(::Windows::Media::Capture::MediaCaptureStopResult^ 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::MediaCaptureStopResult^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureStopResult^>(info[0])) {
        try {
          winRtInstance = (::Windows::Media::Capture::MediaCaptureStopResult^) 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());

      MediaCaptureStopResult *wrapperInstance = new MediaCaptureStopResult(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::MediaCaptureStopResult^>(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::MediaCaptureStopResult^ winRtInstance;
      try {
        winRtInstance = (::Windows::Media::Capture::MediaCaptureStopResult^) NodeRT::Utils::GetObjectInstance(info[0]);
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }

      info.GetReturnValue().Set(WrapMediaCaptureStopResult(winRtInstance));
    }



    static void Close(Nan::NAN_METHOD_ARGS_TYPE info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureStopResult^>(info.This())) {
        return;
      }

      MediaCaptureStopResult *wrapper = MediaCaptureStopResult::Unwrap<MediaCaptureStopResult>(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 LastFrameGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureStopResult^>(info.This())) {
        return;
      }

      MediaCaptureStopResult *wrapper = MediaCaptureStopResult::Unwrap<MediaCaptureStopResult>(info.This());

      try  {
        ::Windows::Media::VideoFrame^ result = wrapper->_instance->LastFrame;
        info.GetReturnValue().Set(NodeRT::Utils::CreateExternalWinRTObject("Windows.Media", "VideoFrame", result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void RecordDurationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info) {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Media::Capture::MediaCaptureStopResult^>(info.This())) {
        return;
      }

      MediaCaptureStopResult *wrapper = MediaCaptureStopResult::Unwrap<MediaCaptureStopResult>(info.This());

      try  {
        ::Windows::Foundation::TimeSpan result = wrapper->_instance->RecordDuration;
        info.GetReturnValue().Set(Nan::New<Number>(result.Duration/10000.0));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      


    private:
      ::Windows::Media::Capture::MediaCaptureStopResult^ _instance;
      static Persistent<FunctionTemplate> s_constructorTemplate;

      friend v8::Local<v8::Value> WrapMediaCaptureStopResult(::Windows::Media::Capture::MediaCaptureStopResult^ wintRtInstance);
      friend ::Windows::Media::Capture::MediaCaptureStopResult^ UnwrapMediaCaptureStopResult(Local<Value> value);
  };

  Persistent<FunctionTemplate> MediaCaptureStopResult::s_constructorTemplate;

  v8::Local<v8::Value> WrapMediaCaptureStopResult(::Windows::Media::Capture::MediaCaptureStopResult^ 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>(MediaCaptureStopResult::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Media::Capture::MediaCaptureStopResult^ UnwrapMediaCaptureStopResult(Local<Value> value) {
     return MediaCaptureStopResult::Unwrap<MediaCaptureStopResult>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitMediaCaptureStopResult(Local<Object> exports) {
    MediaCaptureStopResult::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);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("frameBoundsRelativeToReferencePhoto").ToLocalChecked(), FrameBoundsRelativeToReferencePhotoGetter);

        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;
      }
    }
      
    static void FrameBoundsRelativeToReferencePhotoGetter(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::IBox<::Windows::Foundation::Rect>^ result = wrapper->_instance->FrameBoundsRelativeToReferencePhoto;
        info.GetReturnValue().Set(result ? static_cast<Local<Value>>(NodeRT::Utils::RectToJs(result->Value)) : Undefined());
        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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IBuffer", result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        } catch (Platform::Exception^ exception) {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }
    static void 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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              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};


            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) {


            Local<Value> error;
            Local<Value> arg1;
            {
              TryCatch tryCatch;
              arg1 = Nan::New<Boolean>(result);
              if (tryCatch.HasCaught())
              {
                error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
              }
              else
              {
                error = Undefined();
              }
              if (arg1.IsEmpty()) arg1 = Undefined();
            }
            Local<Value> args[] = {error, arg1};


            invokeCallback(_countof(args), args);
          });
        } catch (Platform::Exception^ exception) {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);

            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }
      });
    }

    static void 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>("isHistoricalCaptureEnabled").ToLocalChecked(), IsHistoricalCaptureEnabledGetter, IsHistoricalCaptureEnabledSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isAudioCaptureEnabled").ToLocalChecked(), IsAudioCaptureEnabledGetter, IsAudioCaptureEnabledSetter);
            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>("appCaptureDestinationFolder").ToLocalChecked(), AppCaptureDestinationFolderGetter, AppCaptureDestinationFolderSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isHistoricalCaptureOnBatteryAllowed").ToLocalChecked(), IsHistoricalCaptureOnBatteryAllowedGetter, IsHistoricalCaptureOnBatteryAllowedSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customVideoEncodingWidth").ToLocalChecked(), CustomVideoEncodingWidthGetter, CustomVideoEncodingWidthSetter);
            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>("historicalBufferLength").ToLocalChecked(), HistoricalBufferLengthGetter, HistoricalBufferLengthSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("customVideoEncodingHeight").ToLocalChecked(), CustomVideoEncodingHeightGetter, CustomVideoEncodingHeightSetter);
            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>("isHistoricalCaptureOnWirelessDisplayAllowed").ToLocalChecked(), IsHistoricalCaptureOnWirelessDisplayAllowedGetter, IsHistoricalCaptureOnWirelessDisplayAllowedSetter);
            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);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("videoEncodingFrameRateMode").ToLocalChecked(), VideoEncodingFrameRateModeGetter, VideoEncodingFrameRateModeSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("systemAudioGain").ToLocalChecked(), SystemAudioGainGetter, SystemAudioGainSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("microphoneGain").ToLocalChecked(), MicrophoneGainGetter, MicrophoneGainSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("isMicrophoneCaptureEnabledByDefault").ToLocalChecked(), IsMicrophoneCaptureEnabledByDefaultGetter, IsMicrophoneCaptureEnabledByDefaultSetter);

        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 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 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 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 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 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 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 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 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 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 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 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 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);
      }
    }
      
    static void VideoEncodingFrameRateModeGetter(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::AppCaptureVideoEncodingFrameRateMode result = wrapper->_instance->VideoEncodingFrameRateMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void VideoEncodingFrameRateModeSetter(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::AppCaptureVideoEncodingFrameRateMode winRtValue = static_cast<::Windows::Media::Capture::AppCaptureVideoEncodingFrameRateMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->VideoEncodingFrameRateMode = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void SystemAudioGainGetter(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  {
        double result = wrapper->_instance->SystemAudioGain;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void SystemAudioGainSetter(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 {

        double winRtValue = Nan::To<double>(value).FromMaybe(0.0);

        wrapper->_instance->SystemAudioGain = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void MicrophoneGainGetter(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  {
        double result = wrapper->_instance->MicrophoneGain;
        info.GetReturnValue().Set(Nan::New<Number>(static_cast<double>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void MicrophoneGainSetter(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 {

        double winRtValue = Nan::To<double>(value).FromMaybe(0.0);

        wrapper->_instance->MicrophoneGain = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void IsMicrophoneCaptureEnabledByDefaultGetter(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->IsMicrophoneCaptureEnabledByDefault;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void IsMicrophoneCaptureEnabledByDefaultSetter(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->IsMicrophoneCaptureEnabledByDefault = 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);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleCameraCaptureKeyModifiers").ToLocalChecked(), ToggleCameraCaptureKeyModifiersGetter, ToggleCameraCaptureKeyModifiersSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleCameraCaptureKey").ToLocalChecked(), ToggleCameraCaptureKeyGetter, ToggleCameraCaptureKeySetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleBroadcastKeyModifiers").ToLocalChecked(), ToggleBroadcastKeyModifiersGetter, ToggleBroadcastKeyModifiersSetter);
            Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("toggleBroadcastKey").ToLocalChecked(), ToggleBroadcastKeyGetter, ToggleBroadcastKeySetter);

        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);
      }
    }
      
    static void ToggleCameraCaptureKeyModifiersGetter(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->ToggleCameraCaptureKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ToggleCameraCaptureKeyModifiersSetter(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->ToggleCameraCaptureKeyModifiers = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ToggleCameraCaptureKeyGetter(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->ToggleCameraCaptureKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ToggleCameraCaptureKeySetter(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->ToggleCameraCaptureKey = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ToggleBroadcastKeyModifiersGetter(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->ToggleBroadcastKeyModifiers;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ToggleBroadcastKeyModifiersSetter(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->ToggleBroadcastKeyModifiers = winRtValue;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
      
    static void ToggleBroadcastKeyGetter(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->ToggleBroadcastKey;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      } catch (Platform::Exception ^exception) {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
      
    static void ToggleBroadcastKeySetter(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->ToggleBroadcastKey = 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(v8::Isolate::GetCurrent(), 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;


                Local<Value> wrappedArg0;
                Local<Value> wrappedArg1;

                {
                  TryCatch tryCatch;


                  wrappedArg0 = WrapScreenCapture(arg0);
                  wrappedArg1 = WrapSourceSuspensionChangedEventArgs(arg1);


                  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(v8::Isolate::GetCurrent(), 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(v8::Isolate::GetCurrent(), info[0]);
      auto str = *eventName;

      if ((!NodeRT::Utils::CaseInsenstiveEquals(L"sourceSuspensionChanged", str))) {
        Nan::ThrowError(Nan::Error(String::Concat(v8::Isolate::GetCurrent(), 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::InitMediaCaptureMemoryPreferenceEnum(target);
      NodeRT::Windows::Media::Capture::InitMediaCaptureSharingModeEnum(target);
      NodeRT::Windows::Media::Capture::InitAppCaptureVideoEncodingBitrateModeEnum(target);
      NodeRT::Windows::Media::Capture::InitAppCaptureVideoEncodingResolutionModeEnum(target);
      NodeRT::Windows::Media::Capture::InitAppCaptureVideoEncodingFrameRateModeEnum(target);
      NodeRT::Windows::Media::Capture::InitAppCaptureHistoricalBufferLengthUnitEnum(target);
      NodeRT::Windows::Media::Capture::InitAppCapture(target);
      NodeRT::Windows::Media::Capture::InitCameraCaptureUIPhotoCaptureSettings(target);
      NodeRT::Windows::Media::Capture::InitCameraCaptureUIVideoCaptureSettings(target);
      NodeRT::Windows::Media::Capture::InitCameraCaptureUI(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::InitMediaCapturePauseResult(target);
      NodeRT::Windows::Media::Capture::InitMediaCaptureStopResult(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)
