// Copyright (c) Microsoft Corporation
// All rights reserved. 
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED ON AN  *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//
// See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.

// TODO: Verify that this is is still needed..
#define NTDDI_VERSION 0x06010000

#include <v8.h>
#include "nan.h"
#include <string>
#include <ppltasks.h>
#include "CollectionsConverter.h"
#include "CollectionsWrap.h"
#include "node-async.h"
#include "NodeRtUtils.h"
#include "OpaqueWrapper.h"
#include "WrapperBase.h"

#using <Windows.WinMD>

// this undefs fixes the issues of compiling Windows.Data.Json, Windows.Storag.FileProperties, and Windows.Stroage.Search
// Some of the node header files brings windows definitions with the same names as some of the WinRT methods
#undef DocumentProperties
#undef GetObject
#undef CreateEvent
#undef FindText
#undef SendMessage

const char* REGISTRATION_TOKEN_MAP_PROPERTY_NAME = "__registrationTokenMap__";

using v8::Array;
using v8::String;
using v8::Handle;
using v8::Value;
using v8::Boolean;
using v8::Integer;
using v8::FunctionTemplate;
using v8::Object;
using v8::Local;
using v8::Function;
using v8::Date;
using v8::Number;
using v8::PropertyAttribute;
using v8::Primitive;
using Nan::HandleScope;
using Nan::Persistent;
using Nan::Undefined;
using Nan::True;
using Nan::False;
using Nan::Null;
using Nan::MaybeLocal;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::TryCatch;
using namespace concurrency;

namespace NodeRT { namespace Windows { namespace Devices { namespace Scanners { 

  v8::Local<v8::Value> WrapIImageScannerFormatConfiguration(::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ wintRtInstance);
  ::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ UnwrapIImageScannerFormatConfiguration(Local<Value> value);
  
  v8::Local<v8::Value> WrapImageScannerAutoConfiguration(::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ wintRtInstance);
  ::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ UnwrapImageScannerAutoConfiguration(Local<Value> value);
  
  v8::Local<v8::Value> WrapIImageScannerSourceConfiguration(::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ wintRtInstance);
  ::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ UnwrapIImageScannerSourceConfiguration(Local<Value> value);
  
  v8::Local<v8::Value> WrapImageScannerFlatbedConfiguration(::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ wintRtInstance);
  ::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ UnwrapImageScannerFlatbedConfiguration(Local<Value> value);
  
  v8::Local<v8::Value> WrapImageScannerFeederConfiguration(::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ wintRtInstance);
  ::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ UnwrapImageScannerFeederConfiguration(Local<Value> value);
  
  v8::Local<v8::Value> WrapImageScannerScanResult(::Windows::Devices::Scanners::ImageScannerScanResult^ wintRtInstance);
  ::Windows::Devices::Scanners::ImageScannerScanResult^ UnwrapImageScannerScanResult(Local<Value> value);
  
  v8::Local<v8::Value> WrapImageScannerPreviewResult(::Windows::Devices::Scanners::ImageScannerPreviewResult^ wintRtInstance);
  ::Windows::Devices::Scanners::ImageScannerPreviewResult^ UnwrapImageScannerPreviewResult(Local<Value> value);
  
  v8::Local<v8::Value> WrapImageScanner(::Windows::Devices::Scanners::ImageScanner^ wintRtInstance);
  ::Windows::Devices::Scanners::ImageScanner^ UnwrapImageScanner(Local<Value> value);
  


  static void InitImageScannerFormatEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("ImageScannerFormat").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("jpeg").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerFormat::Jpeg)));
	Nan::Set(enumObject, Nan::New<String>("png").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerFormat::Png)));
	Nan::Set(enumObject, Nan::New<String>("deviceIndependentBitmap").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerFormat::DeviceIndependentBitmap)));
	Nan::Set(enumObject, Nan::New<String>("tiff").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerFormat::Tiff)));
	Nan::Set(enumObject, Nan::New<String>("xps").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerFormat::Xps)));
	Nan::Set(enumObject, Nan::New<String>("openXps").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerFormat::OpenXps)));
	Nan::Set(enumObject, Nan::New<String>("pdf").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerFormat::Pdf)));
  }


  static void InitImageScannerAutoCroppingModeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("ImageScannerAutoCroppingMode").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("disabled").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerAutoCroppingMode::Disabled)));
	Nan::Set(enumObject, Nan::New<String>("singleRegion").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerAutoCroppingMode::SingleRegion)));
	Nan::Set(enumObject, Nan::New<String>("multipleRegion").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerAutoCroppingMode::MultipleRegion)));
  }


  static void InitImageScannerColorModeEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("ImageScannerColorMode").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("color").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerColorMode::Color)));
	Nan::Set(enumObject, Nan::New<String>("grayscale").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerColorMode::Grayscale)));
	Nan::Set(enumObject, Nan::New<String>("monochrome").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerColorMode::Monochrome)));
	Nan::Set(enumObject, Nan::New<String>("autoColor").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerColorMode::AutoColor)));
  }


  static void InitImageScannerScanSourceEnum(const Local<Object> exports)
  {
    HandleScope scope;
    
	Local<Object> enumObject = Nan::New<Object>();
    Nan::Set(exports, Nan::New<String>("ImageScannerScanSource").ToLocalChecked(), enumObject);
	Nan::Set(enumObject, Nan::New<String>("default").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerScanSource::Default)));
	Nan::Set(enumObject, Nan::New<String>("flatbed").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerScanSource::Flatbed)));
	Nan::Set(enumObject, Nan::New<String>("feeder").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerScanSource::Feeder)));
	Nan::Set(enumObject, Nan::New<String>("autoConfigured").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Devices::Scanners::ImageScannerScanSource::AutoConfigured)));
  }



  
  static bool IsScannerDeviceContractJsObject(Local<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    return true;
  }

  ::Windows::Devices::Scanners::ScannerDeviceContract ScannerDeviceContractFromJsObject(Local<Value> value)
  {
    HandleScope scope;
    ::Windows::Devices::Scanners::ScannerDeviceContract 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> ScannerDeviceContractToJsObject(::Windows::Devices::Scanners::ScannerDeviceContract value)
  {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();

    
    return scope.Escape(obj);
  }

  
  static bool IsImageScannerResolutionJsObject(Local<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Local<String> symbol;
    Local<Object> obj = Nan::To<Object>(value).ToLocalChecked();

    symbol = Nan::New<String>("dpiX").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      if (!Nan::Get(obj,symbol).ToLocalChecked()->IsNumber())
      {
          return false;
      }
    }
    
    symbol = Nan::New<String>("dpiY").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      if (!Nan::Get(obj,symbol).ToLocalChecked()->IsNumber())
      {
          return false;
      }
    }
    
    return true;
  }

  ::Windows::Devices::Scanners::ImageScannerResolution ImageScannerResolutionFromJsObject(Local<Value> value)
  {
    HandleScope scope;
    ::Windows::Devices::Scanners::ImageScannerResolution 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>("dpiX").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      returnValue.DpiX = static_cast<float>(Nan::To<double>(Nan::Get(obj,symbol).ToLocalChecked()).FromMaybe(0.0));
    }
    
    symbol = Nan::New<String>("dpiY").ToLocalChecked();
    if (Nan::Has(obj, symbol).FromMaybe(false))
    {
      returnValue.DpiY = static_cast<float>(Nan::To<double>(Nan::Get(obj,symbol).ToLocalChecked()).FromMaybe(0.0));
    }
    
    return returnValue;
  }

  Local<Value> ImageScannerResolutionToJsObject(::Windows::Devices::Scanners::ImageScannerResolution value)
  {
    EscapableHandleScope scope;

    Local<Object> obj = Nan::New<Object>();

    Nan::Set(obj, Nan::New<String>("dpiX").ToLocalChecked(), Nan::New<Number>(static_cast<double>(value.DpiX)));
    Nan::Set(obj, Nan::New<String>("dpiY").ToLocalChecked(), Nan::New<Number>(static_cast<double>(value.DpiY)));
    
    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 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 IImageScannerFormatConfiguration : 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>("IImageScannerFormatConfiguration").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "isFormatSupported", IsFormatSupported);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultFormat").ToLocalChecked(), DefaultFormatGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("format").ToLocalChecked(), FormatGetter, FormatSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IImageScannerFormatConfiguration").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IImageScannerFormatConfiguration(::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ 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::Devices::Scanners::IImageScannerFormatConfiguration^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerFormatConfiguration^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::IImageScannerFormatConfiguration^) 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());

      IImageScannerFormatConfiguration *wrapperInstance = new IImageScannerFormatConfiguration(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::Devices::Scanners::IImageScannerFormatConfiguration^>(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::Devices::Scanners::IImageScannerFormatConfiguration^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::IImageScannerFormatConfiguration^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIImageScannerFormatConfiguration(winRtInstance));
    }


  
    static void IsFormatSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerFormatConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerFormatConfiguration *wrapper = IImageScannerFormatConfiguration::Unwrap<IImageScannerFormatConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerFormat arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsFormatSupported(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 DefaultFormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerFormatConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerFormatConfiguration *wrapper = IImageScannerFormatConfiguration::Unwrap<IImageScannerFormatConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat result = wrapper->_instance->DefaultFormat;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerFormatConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerFormatConfiguration *wrapper = IImageScannerFormatConfiguration::Unwrap<IImageScannerFormatConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat 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::Devices::Scanners::IImageScannerFormatConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerFormatConfiguration *wrapper = IImageScannerFormatConfiguration::Unwrap<IImageScannerFormatConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerFormat winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Format = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIImageScannerFormatConfiguration(::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ wintRtInstance);
    friend ::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ UnwrapIImageScannerFormatConfiguration(Local<Value> value);
  };
  Persistent<FunctionTemplate> IImageScannerFormatConfiguration::s_constructorTemplate;

  v8::Local<v8::Value> WrapIImageScannerFormatConfiguration(::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ 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>(IImageScannerFormatConfiguration::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::IImageScannerFormatConfiguration^ UnwrapIImageScannerFormatConfiguration(Local<Value> value)
  {
     return IImageScannerFormatConfiguration::Unwrap<IImageScannerFormatConfiguration>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIImageScannerFormatConfiguration(Local<Object> exports)
  {
    IImageScannerFormatConfiguration::Init(exports);
  }

  class ImageScannerAutoConfiguration : 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>("ImageScannerAutoConfiguration").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "isFormatSupported", IsFormatSupported);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("format").ToLocalChecked(), FormatGetter, FormatSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultFormat").ToLocalChecked(), DefaultFormatGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("ImageScannerAutoConfiguration").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ImageScannerAutoConfiguration(::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ 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::Devices::Scanners::ImageScannerAutoConfiguration^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerAutoConfiguration^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::ImageScannerAutoConfiguration^) 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());

      ImageScannerAutoConfiguration *wrapperInstance = new ImageScannerAutoConfiguration(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::Devices::Scanners::ImageScannerAutoConfiguration^>(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::Devices::Scanners::ImageScannerAutoConfiguration^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::ImageScannerAutoConfiguration^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapImageScannerAutoConfiguration(winRtInstance));
    }


  
    static void IsFormatSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerAutoConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerAutoConfiguration *wrapper = ImageScannerAutoConfiguration::Unwrap<ImageScannerAutoConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerFormat arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsFormatSupported(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 FormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerAutoConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerAutoConfiguration *wrapper = ImageScannerAutoConfiguration::Unwrap<ImageScannerAutoConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat 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::Devices::Scanners::ImageScannerAutoConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerAutoConfiguration *wrapper = ImageScannerAutoConfiguration::Unwrap<ImageScannerAutoConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerFormat winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Format = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DefaultFormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerAutoConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerAutoConfiguration *wrapper = ImageScannerAutoConfiguration::Unwrap<ImageScannerAutoConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat result = wrapper->_instance->DefaultFormat;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapImageScannerAutoConfiguration(::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ wintRtInstance);
    friend ::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ UnwrapImageScannerAutoConfiguration(Local<Value> value);
  };
  Persistent<FunctionTemplate> ImageScannerAutoConfiguration::s_constructorTemplate;

  v8::Local<v8::Value> WrapImageScannerAutoConfiguration(::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ 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>(ImageScannerAutoConfiguration::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ UnwrapImageScannerAutoConfiguration(Local<Value> value)
  {
     return ImageScannerAutoConfiguration::Unwrap<ImageScannerAutoConfiguration>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitImageScannerAutoConfiguration(Local<Object> exports)
  {
    ImageScannerAutoConfiguration::Init(exports);
  }

  class IImageScannerSourceConfiguration : 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>("IImageScannerSourceConfiguration").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "isAutoCroppingModeSupported", IsAutoCroppingModeSupported);
      Nan::SetPrototypeMethod(localRef, "isColorModeSupported", IsColorModeSupported);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("actualResolution").ToLocalChecked(), ActualResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("autoCroppingMode").ToLocalChecked(), AutoCroppingModeGetter, AutoCroppingModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("brightness").ToLocalChecked(), BrightnessGetter, BrightnessSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("brightnessStep").ToLocalChecked(), BrightnessStepGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("colorMode").ToLocalChecked(), ColorModeGetter, ColorModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contrast").ToLocalChecked(), ContrastGetter, ContrastSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contrastStep").ToLocalChecked(), ContrastStepGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultBrightness").ToLocalChecked(), DefaultBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultColorMode").ToLocalChecked(), DefaultColorModeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultContrast").ToLocalChecked(), DefaultContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("desiredResolution").ToLocalChecked(), DesiredResolutionGetter, DesiredResolutionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxBrightness").ToLocalChecked(), MaxBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxContrast").ToLocalChecked(), MaxContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxResolution").ToLocalChecked(), MaxResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxScanArea").ToLocalChecked(), MaxScanAreaGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minBrightness").ToLocalChecked(), MinBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minContrast").ToLocalChecked(), MinContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minResolution").ToLocalChecked(), MinResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minScanArea").ToLocalChecked(), MinScanAreaGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("opticalResolution").ToLocalChecked(), OpticalResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("selectedScanRegion").ToLocalChecked(), SelectedScanRegionGetter, SelectedScanRegionSetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("IImageScannerSourceConfiguration").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IImageScannerSourceConfiguration(::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ 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::Devices::Scanners::IImageScannerSourceConfiguration^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::IImageScannerSourceConfiguration^) 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());

      IImageScannerSourceConfiguration *wrapperInstance = new IImageScannerSourceConfiguration(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::Devices::Scanners::IImageScannerSourceConfiguration^>(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::Devices::Scanners::IImageScannerSourceConfiguration^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::IImageScannerSourceConfiguration^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapIImageScannerSourceConfiguration(winRtInstance));
    }


  
    static void IsAutoCroppingModeSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerAutoCroppingMode>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsAutoCroppingModeSupported(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 IsColorModeSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerColorMode arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerColorMode>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsColorModeSupported(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 ActualResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->ActualResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AutoCroppingModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode result = wrapper->_instance->AutoCroppingMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AutoCroppingModeSetter(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::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerAutoCroppingMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->AutoCroppingMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void BrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->Brightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void BrightnessSetter(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::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Brightness = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void BrightnessStepGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->BrightnessStep;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ColorModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerColorMode result = wrapper->_instance->ColorMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ColorModeSetter(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::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerColorMode winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerColorMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ColorMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->Contrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ContrastSetter(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::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Contrast = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ContrastStepGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ContrastStep;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->DefaultBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultColorModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerColorMode result = wrapper->_instance->DefaultColorMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->DefaultContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DesiredResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->DesiredResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DesiredResolutionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!IsImageScannerResolutionJsObject(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerResolution winRtValue = ImageScannerResolutionFromJsObject(value);

        wrapper->_instance->DesiredResolution = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void MaxBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MaxBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MaxContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->MaxResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxScanAreaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->MaxScanArea;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MinBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MinContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->MinResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinScanAreaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->MinScanArea;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void OpticalResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->OpticalResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SelectedScanRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Rect result = wrapper->_instance->SelectedScanRegion;
        info.GetReturnValue().Set(NodeRT::Utils::RectToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SelectedScanRegionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsRect(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::IImageScannerSourceConfiguration^>(info.This()))
      {
        return;
      }

      IImageScannerSourceConfiguration *wrapper = IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(info.This());

      try 
      {
        
        ::Windows::Foundation::Rect winRtValue = NodeRT::Utils::RectFromJs(value);

        wrapper->_instance->SelectedScanRegion = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapIImageScannerSourceConfiguration(::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ wintRtInstance);
    friend ::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ UnwrapIImageScannerSourceConfiguration(Local<Value> value);
  };
  Persistent<FunctionTemplate> IImageScannerSourceConfiguration::s_constructorTemplate;

  v8::Local<v8::Value> WrapIImageScannerSourceConfiguration(::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ 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>(IImageScannerSourceConfiguration::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::IImageScannerSourceConfiguration^ UnwrapIImageScannerSourceConfiguration(Local<Value> value)
  {
     return IImageScannerSourceConfiguration::Unwrap<IImageScannerSourceConfiguration>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitIImageScannerSourceConfiguration(Local<Object> exports)
  {
    IImageScannerSourceConfiguration::Init(exports);
  }

  class ImageScannerFlatbedConfiguration : 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>("ImageScannerFlatbedConfiguration").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "isFormatSupported", IsFormatSupported);
      Nan::SetPrototypeMethod(localRef, "isAutoCroppingModeSupported", IsAutoCroppingModeSupported);
      Nan::SetPrototypeMethod(localRef, "isColorModeSupported", IsColorModeSupported);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("format").ToLocalChecked(), FormatGetter, FormatSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultFormat").ToLocalChecked(), DefaultFormatGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("selectedScanRegion").ToLocalChecked(), SelectedScanRegionGetter, SelectedScanRegionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("desiredResolution").ToLocalChecked(), DesiredResolutionGetter, DesiredResolutionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contrast").ToLocalChecked(), ContrastGetter, ContrastSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("brightness").ToLocalChecked(), BrightnessGetter, BrightnessSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("autoCroppingMode").ToLocalChecked(), AutoCroppingModeGetter, AutoCroppingModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("colorMode").ToLocalChecked(), ColorModeGetter, ColorModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contrastStep").ToLocalChecked(), ContrastStepGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultBrightness").ToLocalChecked(), DefaultBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultColorMode").ToLocalChecked(), DefaultColorModeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultContrast").ToLocalChecked(), DefaultContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("actualResolution").ToLocalChecked(), ActualResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxBrightness").ToLocalChecked(), MaxBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxContrast").ToLocalChecked(), MaxContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxResolution").ToLocalChecked(), MaxResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxScanArea").ToLocalChecked(), MaxScanAreaGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minBrightness").ToLocalChecked(), MinBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("brightnessStep").ToLocalChecked(), BrightnessStepGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minContrast").ToLocalChecked(), MinContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minResolution").ToLocalChecked(), MinResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("opticalResolution").ToLocalChecked(), OpticalResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minScanArea").ToLocalChecked(), MinScanAreaGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("ImageScannerFlatbedConfiguration").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ImageScannerFlatbedConfiguration(::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ 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::Devices::Scanners::ImageScannerFlatbedConfiguration^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^) 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());

      ImageScannerFlatbedConfiguration *wrapperInstance = new ImageScannerFlatbedConfiguration(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::Devices::Scanners::ImageScannerFlatbedConfiguration^>(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::Devices::Scanners::ImageScannerFlatbedConfiguration^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapImageScannerFlatbedConfiguration(winRtInstance));
    }


  
    static void IsFormatSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerFormat arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsFormatSupported(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 IsAutoCroppingModeSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerAutoCroppingMode>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsAutoCroppingModeSupported(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 IsColorModeSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerColorMode arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerColorMode>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsColorModeSupported(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 FormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat 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::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerFormat winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Format = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DefaultFormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat result = wrapper->_instance->DefaultFormat;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SelectedScanRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Rect result = wrapper->_instance->SelectedScanRegion;
        info.GetReturnValue().Set(NodeRT::Utils::RectToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SelectedScanRegionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsRect(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        
        ::Windows::Foundation::Rect winRtValue = NodeRT::Utils::RectFromJs(value);

        wrapper->_instance->SelectedScanRegion = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DesiredResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->DesiredResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DesiredResolutionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!IsImageScannerResolutionJsObject(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerResolution winRtValue = ImageScannerResolutionFromJsObject(value);

        wrapper->_instance->DesiredResolution = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->Contrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ContrastSetter(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::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Contrast = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void BrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->Brightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void BrightnessSetter(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::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Brightness = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AutoCroppingModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode result = wrapper->_instance->AutoCroppingMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AutoCroppingModeSetter(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::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerAutoCroppingMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->AutoCroppingMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ColorModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerColorMode result = wrapper->_instance->ColorMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ColorModeSetter(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::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerColorMode winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerColorMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ColorMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ContrastStepGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ContrastStep;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->DefaultBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultColorModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerColorMode result = wrapper->_instance->DefaultColorMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->DefaultContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ActualResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->ActualResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MaxBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MaxContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->MaxResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxScanAreaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->MaxScanArea;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MinBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void BrightnessStepGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->BrightnessStep;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MinContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->MinResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void OpticalResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->OpticalResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinScanAreaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFlatbedConfiguration *wrapper = ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->MinScanArea;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapImageScannerFlatbedConfiguration(::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ wintRtInstance);
    friend ::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ UnwrapImageScannerFlatbedConfiguration(Local<Value> value);
  };
  Persistent<FunctionTemplate> ImageScannerFlatbedConfiguration::s_constructorTemplate;

  v8::Local<v8::Value> WrapImageScannerFlatbedConfiguration(::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ 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>(ImageScannerFlatbedConfiguration::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ UnwrapImageScannerFlatbedConfiguration(Local<Value> value)
  {
     return ImageScannerFlatbedConfiguration::Unwrap<ImageScannerFlatbedConfiguration>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitImageScannerFlatbedConfiguration(Local<Object> exports)
  {
    ImageScannerFlatbedConfiguration::Init(exports);
  }

  class ImageScannerFeederConfiguration : 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>("ImageScannerFeederConfiguration").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      Nan::SetPrototypeMethod(localRef, "isFormatSupported", IsFormatSupported);
      Nan::SetPrototypeMethod(localRef, "isAutoCroppingModeSupported", IsAutoCroppingModeSupported);
      Nan::SetPrototypeMethod(localRef, "isColorModeSupported", IsColorModeSupported);
      Nan::SetPrototypeMethod(localRef, "isPageSizeSupported", IsPageSizeSupported);
      
                        
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("scanAhead").ToLocalChecked(), ScanAheadGetter, ScanAheadSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("autoDetectPageSize").ToLocalChecked(), AutoDetectPageSizeGetter, AutoDetectPageSizeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("duplex").ToLocalChecked(), DuplexGetter, DuplexSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxNumberOfPages").ToLocalChecked(), MaxNumberOfPagesGetter, MaxNumberOfPagesSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("pageOrientation").ToLocalChecked(), PageOrientationGetter, PageOrientationSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("pageSize").ToLocalChecked(), PageSizeGetter, PageSizeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("pageSizeDimensions").ToLocalChecked(), PageSizeDimensionsGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("canScanDuplex").ToLocalChecked(), CanScanDuplexGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("canScanAhead").ToLocalChecked(), CanScanAheadGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("canAutoDetectPageSize").ToLocalChecked(), CanAutoDetectPageSizeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("format").ToLocalChecked(), FormatGetter, FormatSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultFormat").ToLocalChecked(), DefaultFormatGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("desiredResolution").ToLocalChecked(), DesiredResolutionGetter, DesiredResolutionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contrast").ToLocalChecked(), ContrastGetter, ContrastSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("colorMode").ToLocalChecked(), ColorModeGetter, ColorModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("autoCroppingMode").ToLocalChecked(), AutoCroppingModeGetter, AutoCroppingModeSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("brightness").ToLocalChecked(), BrightnessGetter, BrightnessSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("selectedScanRegion").ToLocalChecked(), SelectedScanRegionGetter, SelectedScanRegionSetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minBrightness").ToLocalChecked(), MinBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minContrast").ToLocalChecked(), MinContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minResolution").ToLocalChecked(), MinResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("minScanArea").ToLocalChecked(), MinScanAreaGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("opticalResolution").ToLocalChecked(), OpticalResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxScanArea").ToLocalChecked(), MaxScanAreaGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxResolution").ToLocalChecked(), MaxResolutionGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxContrast").ToLocalChecked(), MaxContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("maxBrightness").ToLocalChecked(), MaxBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultContrast").ToLocalChecked(), DefaultContrastGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultColorMode").ToLocalChecked(), DefaultColorModeGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultBrightness").ToLocalChecked(), DefaultBrightnessGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("contrastStep").ToLocalChecked(), ContrastStepGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("brightnessStep").ToLocalChecked(), BrightnessStepGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("actualResolution").ToLocalChecked(), ActualResolutionGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("ImageScannerFeederConfiguration").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ImageScannerFeederConfiguration(::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ 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::Devices::Scanners::ImageScannerFeederConfiguration^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::ImageScannerFeederConfiguration^) 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());

      ImageScannerFeederConfiguration *wrapperInstance = new ImageScannerFeederConfiguration(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::Devices::Scanners::ImageScannerFeederConfiguration^>(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::Devices::Scanners::ImageScannerFeederConfiguration^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::ImageScannerFeederConfiguration^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapImageScannerFeederConfiguration(winRtInstance));
    }


  
    static void IsFormatSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerFormat arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsFormatSupported(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 IsAutoCroppingModeSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerAutoCroppingMode>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsAutoCroppingModeSupported(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 IsColorModeSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerColorMode arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerColorMode>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsColorModeSupported(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 IsPageSizeSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      if (info.Length() == 2
        && info[0]->IsInt32()
        && info[1]->IsInt32())
      {
        try
        {
          ::Windows::Graphics::Printing::PrintMediaSize arg0 = static_cast<::Windows::Graphics::Printing::PrintMediaSize>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Windows::Graphics::Printing::PrintOrientation arg1 = static_cast<::Windows::Graphics::Printing::PrintOrientation>(Nan::To<int32_t>(info[1]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsPageSizeSupported(arg0, arg1);
          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 ScanAheadGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        bool result = wrapper->_instance->ScanAhead;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ScanAheadSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->ScanAhead = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AutoDetectPageSizeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        bool result = wrapper->_instance->AutoDetectPageSize;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AutoDetectPageSizeSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->AutoDetectPageSize = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DuplexGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        bool result = wrapper->_instance->Duplex;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DuplexSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        bool winRtValue = Nan::To<bool>(value).FromMaybe(false);

        wrapper->_instance->Duplex = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void MaxNumberOfPagesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->MaxNumberOfPages;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxNumberOfPagesSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        unsigned int winRtValue = static_cast<unsigned int>(Nan::To<uint32_t>(value).FromMaybe(0));

        wrapper->_instance->MaxNumberOfPages = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void PageOrientationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Graphics::Printing::PrintOrientation result = wrapper->_instance->PageOrientation;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PageOrientationSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        ::Windows::Graphics::Printing::PrintOrientation winRtValue = static_cast<::Windows::Graphics::Printing::PrintOrientation>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->PageOrientation = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void PageSizeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Graphics::Printing::PrintMediaSize result = wrapper->_instance->PageSize;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void PageSizeSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        ::Windows::Graphics::Printing::PrintMediaSize winRtValue = static_cast<::Windows::Graphics::Printing::PrintMediaSize>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->PageSize = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void PageSizeDimensionsGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->PageSizeDimensions;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CanScanDuplexGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        bool result = wrapper->_instance->CanScanDuplex;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CanScanAheadGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        bool result = wrapper->_instance->CanScanAhead;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void CanAutoDetectPageSizeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        bool result = wrapper->_instance->CanAutoDetectPageSize;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat 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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerFormat winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerFormat>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Format = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void DefaultFormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat result = wrapper->_instance->DefaultFormat;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DesiredResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->DesiredResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DesiredResolutionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!IsImageScannerResolutionJsObject(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerResolution winRtValue = ImageScannerResolutionFromJsObject(value);

        wrapper->_instance->DesiredResolution = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->Contrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ContrastSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Contrast = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void ColorModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerColorMode result = wrapper->_instance->ColorMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ColorModeSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerColorMode winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerColorMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->ColorMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void AutoCroppingModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode result = wrapper->_instance->AutoCroppingMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void AutoCroppingModeSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        ::Windows::Devices::Scanners::ImageScannerAutoCroppingMode winRtValue = static_cast<::Windows::Devices::Scanners::ImageScannerAutoCroppingMode>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->AutoCroppingMode = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void BrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->Brightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void BrightnessSetter(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::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        int winRtValue = static_cast<int>(Nan::To<int32_t>(value).FromMaybe(0));

        wrapper->_instance->Brightness = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void SelectedScanRegionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Rect result = wrapper->_instance->SelectedScanRegion;
        info.GetReturnValue().Set(NodeRT::Utils::RectToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void SelectedScanRegionSetter(Local<String> property, Local<Value> value, const Nan::PropertyCallbackInfo<void> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsRect(value))
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        
        ::Windows::Foundation::Rect winRtValue = NodeRT::Utils::RectFromJs(value);

        wrapper->_instance->SelectedScanRegion = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static void MinBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MinBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MinContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->MinResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MinScanAreaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->MinScanArea;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void OpticalResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->OpticalResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxScanAreaGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Foundation::Size result = wrapper->_instance->MaxScanArea;
        info.GetReturnValue().Set(NodeRT::Utils::SizeToJs(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->MaxResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MaxContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void MaxBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->MaxBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultContrastGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->DefaultContrast;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultColorModeGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerColorMode result = wrapper->_instance->DefaultColorMode;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultBrightnessGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        int result = wrapper->_instance->DefaultBrightness;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ContrastStepGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->ContrastStep;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void BrightnessStepGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        unsigned int result = wrapper->_instance->BrightnessStep;
        info.GetReturnValue().Set(Nan::New<Integer>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void ActualResolutionGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerFeederConfiguration^>(info.This()))
      {
        return;
      }

      ImageScannerFeederConfiguration *wrapper = ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerResolution result = wrapper->_instance->ActualResolution;
        info.GetReturnValue().Set(ImageScannerResolutionToJsObject(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapImageScannerFeederConfiguration(::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ wintRtInstance);
    friend ::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ UnwrapImageScannerFeederConfiguration(Local<Value> value);
  };
  Persistent<FunctionTemplate> ImageScannerFeederConfiguration::s_constructorTemplate;

  v8::Local<v8::Value> WrapImageScannerFeederConfiguration(::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ 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>(ImageScannerFeederConfiguration::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ UnwrapImageScannerFeederConfiguration(Local<Value> value)
  {
     return ImageScannerFeederConfiguration::Unwrap<ImageScannerFeederConfiguration>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitImageScannerFeederConfiguration(Local<Object> exports)
  {
    ImageScannerFeederConfiguration::Init(exports);
  }

  class ImageScannerScanResult : 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>("ImageScannerScanResult").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("scannedFiles").ToLocalChecked(), ScannedFilesGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("ImageScannerScanResult").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ImageScannerScanResult(::Windows::Devices::Scanners::ImageScannerScanResult^ 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::Devices::Scanners::ImageScannerScanResult^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerScanResult^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::ImageScannerScanResult^) 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());

      ImageScannerScanResult *wrapperInstance = new ImageScannerScanResult(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::Devices::Scanners::ImageScannerScanResult^>(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::Devices::Scanners::ImageScannerScanResult^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::ImageScannerScanResult^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapImageScannerScanResult(winRtInstance));
    }


  



    static void ScannedFilesGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerScanResult^>(info.This()))
      {
        return;
      }

      ImageScannerScanResult *wrapper = ImageScannerScanResult::Unwrap<ImageScannerScanResult>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFile^>^ result = wrapper->_instance->ScannedFiles;
        info.GetReturnValue().Set(NodeRT::Collections::VectorViewWrapper<::Windows::Storage::StorageFile^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::StorageFile^ val) -> Local<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFile", val);
            },
            [](Local<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFile^>(value);
            },
            [](Local<Value> value) -> ::Windows::Storage::StorageFile^ {
              return dynamic_cast<::Windows::Storage::StorageFile^>(NodeRT::Utils::GetObjectInstance(value));
            }
          ));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Devices::Scanners::ImageScannerScanResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapImageScannerScanResult(::Windows::Devices::Scanners::ImageScannerScanResult^ wintRtInstance);
    friend ::Windows::Devices::Scanners::ImageScannerScanResult^ UnwrapImageScannerScanResult(Local<Value> value);
  };
  Persistent<FunctionTemplate> ImageScannerScanResult::s_constructorTemplate;

  v8::Local<v8::Value> WrapImageScannerScanResult(::Windows::Devices::Scanners::ImageScannerScanResult^ 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>(ImageScannerScanResult::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::ImageScannerScanResult^ UnwrapImageScannerScanResult(Local<Value> value)
  {
     return ImageScannerScanResult::Unwrap<ImageScannerScanResult>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitImageScannerScanResult(Local<Object> exports)
  {
    ImageScannerScanResult::Init(exports);
  }

  class ImageScannerPreviewResult : 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>("ImageScannerPreviewResult").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("format").ToLocalChecked(), FormatGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("succeeded").ToLocalChecked(), SucceededGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);


      Nan::Set(exports, Nan::New<String>("ImageScannerPreviewResult").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ImageScannerPreviewResult(::Windows::Devices::Scanners::ImageScannerPreviewResult^ 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::Devices::Scanners::ImageScannerPreviewResult^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerPreviewResult^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::ImageScannerPreviewResult^) 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());

      ImageScannerPreviewResult *wrapperInstance = new ImageScannerPreviewResult(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::Devices::Scanners::ImageScannerPreviewResult^>(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::Devices::Scanners::ImageScannerPreviewResult^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::ImageScannerPreviewResult^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapImageScannerPreviewResult(winRtInstance));
    }


  



    static void FormatGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerPreviewResult^>(info.This()))
      {
        return;
      }

      ImageScannerPreviewResult *wrapper = ImageScannerPreviewResult::Unwrap<ImageScannerPreviewResult>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFormat 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 SucceededGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScannerPreviewResult^>(info.This()))
      {
        return;
      }

      ImageScannerPreviewResult *wrapper = ImageScannerPreviewResult::Unwrap<ImageScannerPreviewResult>(info.This());

      try 
      {
        bool result = wrapper->_instance->Succeeded;
        info.GetReturnValue().Set(Nan::New<Boolean>(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Devices::Scanners::ImageScannerPreviewResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapImageScannerPreviewResult(::Windows::Devices::Scanners::ImageScannerPreviewResult^ wintRtInstance);
    friend ::Windows::Devices::Scanners::ImageScannerPreviewResult^ UnwrapImageScannerPreviewResult(Local<Value> value);
  };
  Persistent<FunctionTemplate> ImageScannerPreviewResult::s_constructorTemplate;

  v8::Local<v8::Value> WrapImageScannerPreviewResult(::Windows::Devices::Scanners::ImageScannerPreviewResult^ 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>(ImageScannerPreviewResult::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::ImageScannerPreviewResult^ UnwrapImageScannerPreviewResult(Local<Value> value)
  {
     return ImageScannerPreviewResult::Unwrap<ImageScannerPreviewResult>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitImageScannerPreviewResult(Local<Object> exports)
  {
    ImageScannerPreviewResult::Init(exports);
  }

  class ImageScanner : 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>("ImageScanner").ToLocalChecked());
      localRef->InstanceTemplate()->SetInternalFieldCount(1);
      
      Local<Function> func;
      Local<FunctionTemplate> funcTemplate;
            
      Nan::SetPrototypeMethod(localRef, "isScanSourceSupported", IsScanSourceSupported);
      Nan::SetPrototypeMethod(localRef, "isPreviewSupported", IsPreviewSupported);
      
            
      Nan::SetPrototypeMethod(localRef, "scanPreviewToStreamAsync", ScanPreviewToStreamAsync);
      Nan::SetPrototypeMethod(localRef, "scanFilesToFolderAsync", ScanFilesToFolderAsync);
      
                  
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("autoConfiguration").ToLocalChecked(), AutoConfigurationGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("defaultScanSource").ToLocalChecked(), DefaultScanSourceGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("deviceId").ToLocalChecked(), DeviceIdGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("feederConfiguration").ToLocalChecked(), FeederConfigurationGetter);
      Nan::SetAccessor(localRef->PrototypeTemplate(), Nan::New<String>("flatbedConfiguration").ToLocalChecked(), FlatbedConfigurationGetter);
      
      Local<Object> constructor = Nan::To<Object>(Nan::GetFunction(localRef).ToLocalChecked()).ToLocalChecked();
	  Nan::SetMethod(constructor, "castFrom", CastFrom);

      Nan::SetMethod(constructor, "getDeviceSelector", GetDeviceSelector);
      func = Nan::GetFunction(Nan::New<FunctionTemplate>(FromIdAsync)).ToLocalChecked();
      Nan::Set(constructor, Nan::New<String>("fromIdAsync").ToLocalChecked(), func);

      Nan::Set(exports, Nan::New<String>("ImageScanner").ToLocalChecked(), constructor);
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ImageScanner(::Windows::Devices::Scanners::ImageScanner^ 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::Devices::Scanners::ImageScanner^ winRtInstance;


      if (info.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(info[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Devices::Scanners::ImageScanner^) 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());

      ImageScanner *wrapperInstance = new ImageScanner(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::Devices::Scanners::ImageScanner^>(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::Devices::Scanners::ImageScanner^ winRtInstance;
		try
		{
			winRtInstance = (::Windows::Devices::Scanners::ImageScanner^) NodeRT::Utils::GetObjectInstance(info[0]);
		}
		catch (Platform::Exception ^exception)
		{
			NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
			return;
		}

		info.GetReturnValue().Set(WrapImageScanner(winRtInstance));
    }


    static void ScanPreviewToStreamAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(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;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Devices::Scanners::ImageScannerPreviewResult^>^ op;
    

      if (info.Length() == 3
        && info[0]->IsInt32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IRandomAccessStream^>(info[1]))
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerScanSource arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerScanSource>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Windows::Storage::Streams::IRandomAccessStream^ arg1 = dynamic_cast<::Windows::Storage::Streams::IRandomAccessStream^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->ScanPreviewToStreamAsync(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::Devices::Scanners::ImageScannerPreviewResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapImageScannerPreviewResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
    static void ScanFilesToFolderAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(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;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      ::Windows::Foundation::IAsyncOperationWithProgress<::Windows::Devices::Scanners::ImageScannerScanResult^, unsigned int>^ op;
    

      if (info.Length() == 3
        && info[0]->IsInt32()
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFolder^>(info[1]))
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerScanSource arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerScanSource>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          ::Windows::Storage::StorageFolder^ arg1 = dynamic_cast<::Windows::Storage::StorageFolder^>(NodeRT::Utils::GetObjectInstance(info[1]));
          
          op = wrapper->_instance->ScanFilesToFolderAsync(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::Devices::Scanners::ImageScannerScanResult^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapImageScannerScanResult(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

		    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }
  
    static void IsScanSourceSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info.This()))
      {
        return;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerScanSource arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerScanSource>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsScanSourceSupported(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 IsPreviewSupported(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info.This()))
      {
        return;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      if (info.Length() == 1
        && info[0]->IsInt32())
      {
        try
        {
          ::Windows::Devices::Scanners::ImageScannerScanSource arg0 = static_cast<::Windows::Devices::Scanners::ImageScannerScanSource>(Nan::To<int32_t>(info[0]).FromMaybe(0));
          
          bool result;
          result = wrapper->_instance->IsPreviewSupported(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 FromIdAsync(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 0 || !info[info.Length() -1]->IsFunction())
      {
          Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return;
      }

      ::Windows::Foundation::IAsyncOperation<::Windows::Devices::Scanners::ImageScanner^>^ op;
      

      if (info.Length() == 2
        && info[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(info[0])));
          
          op = ::Windows::Devices::Scanners::ImageScanner::FromIdAsync(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::Devices::Scanners::ImageScanner^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {

            
            TryCatch tryCatch;
            Local<Value> error; 
            Local<Value> arg1 = WrapImageScanner(result);
            if (tryCatch.HasCaught())
            {
              error = Nan::To<Object>(tryCatch.Exception()).ToLocalChecked();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Local<Value> args[] = {error, arg1};
			// TODO: this is ugly! Needed due to the possibility of expception occuring inside object convertors
			// can be fixed by wrapping the conversion code in a function and calling it on the fly
			// we must clear the try catch block here so the invoked inner method exception won't get swollen (issue #52) 
			tryCatch.~TryCatch();

	  	    
            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
          
            Local<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Local<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });
    }

    static void GetDeviceSelector(Nan::NAN_METHOD_ARGS_TYPE info)
    {
      HandleScope scope;

      if (info.Length() == 0)
      {
        try
        {
          Platform::String^ result;
          result = ::Windows::Devices::Scanners::ImageScanner::GetDeviceSelector();
          info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
          return;
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return;
        }
      }
      else 
      {
        Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return;
      }
    }

    static void AutoConfigurationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info.This()))
      {
        return;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerAutoConfiguration^ result = wrapper->_instance->AutoConfiguration;
        info.GetReturnValue().Set(WrapImageScannerAutoConfiguration(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DefaultScanSourceGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info.This()))
      {
        return;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerScanSource result = wrapper->_instance->DefaultScanSource;
        info.GetReturnValue().Set(Nan::New<Integer>(static_cast<int>(result)));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void DeviceIdGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info.This()))
      {
        return;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->DeviceId;
        info.GetReturnValue().Set(NodeRT::Utils::NewString(result->Data()));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FeederConfigurationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info.This()))
      {
        return;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFeederConfiguration^ result = wrapper->_instance->FeederConfiguration;
        info.GetReturnValue().Set(WrapImageScannerFeederConfiguration(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    
    static void FlatbedConfigurationGetter(Local<String> property, const Nan::PropertyCallbackInfo<v8::Value> &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Devices::Scanners::ImageScanner^>(info.This()))
      {
        return;
      }

      ImageScanner *wrapper = ImageScanner::Unwrap<ImageScanner>(info.This());

      try 
      {
        ::Windows::Devices::Scanners::ImageScannerFlatbedConfiguration^ result = wrapper->_instance->FlatbedConfiguration;
        info.GetReturnValue().Set(WrapImageScannerFlatbedConfiguration(result));
        return;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return;
      }
    }
    


  private:
    ::Windows::Devices::Scanners::ImageScanner^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Local<v8::Value> WrapImageScanner(::Windows::Devices::Scanners::ImageScanner^ wintRtInstance);
    friend ::Windows::Devices::Scanners::ImageScanner^ UnwrapImageScanner(Local<Value> value);
  };
  Persistent<FunctionTemplate> ImageScanner::s_constructorTemplate;

  v8::Local<v8::Value> WrapImageScanner(::Windows::Devices::Scanners::ImageScanner^ 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>(ImageScanner::s_constructorTemplate);
    return scope.Escape(Nan::NewInstance(Nan::GetFunction(localRef).ToLocalChecked(),_countof(args), args).ToLocalChecked());
  }

  ::Windows::Devices::Scanners::ImageScanner^ UnwrapImageScanner(Local<Value> value)
  {
     return ImageScanner::Unwrap<ImageScanner>(Nan::To<Object>(value).ToLocalChecked())->_instance;
  }

  void InitImageScanner(Local<Object> exports)
  {
    ImageScanner::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::Devices::Scanners::InitImageScannerFormatEnum(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerAutoCroppingModeEnum(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerColorModeEnum(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerScanSourceEnum(target);
  NodeRT::Windows::Devices::Scanners::InitIImageScannerFormatConfiguration(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerAutoConfiguration(target);
  NodeRT::Windows::Devices::Scanners::InitIImageScannerSourceConfiguration(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerFlatbedConfiguration(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerFeederConfiguration(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerScanResult(target);
  NodeRT::Windows::Devices::Scanners::InitImageScannerPreviewResult(target);
  NodeRT::Windows::Devices::Scanners::InitImageScanner(target);

  NodeRT::Utils::RegisterNameSpace("Windows.Devices.Scanners", target);
}


NODE_MODULE(binding, init)