// 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.

#define NTDDI_VERSION 0x06010000

#include <v8.h>
#include <string>
#include <node_object_wrap.h>
#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 namespace v8;
using namespace node;
using namespace concurrency;

namespace NodeRT { namespace Windows { namespace Storage { namespace Search { 
  v8::Handle<v8::Value> WrapContentIndexer(::Windows::Storage::Search::ContentIndexer^ wintRtInstance);
  ::Windows::Storage::Search::ContentIndexer^ UnwrapContentIndexer(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapIIndexableContent(::Windows::Storage::Search::IIndexableContent^ wintRtInstance);
  ::Windows::Storage::Search::IIndexableContent^ UnwrapIIndexableContent(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapValueAndLanguage(::Windows::Storage::Search::ValueAndLanguage^ wintRtInstance);
  ::Windows::Storage::Search::ValueAndLanguage^ UnwrapValueAndLanguage(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapContentIndexerQuery(::Windows::Storage::Search::ContentIndexerQuery^ wintRtInstance);
  ::Windows::Storage::Search::ContentIndexerQuery^ UnwrapContentIndexerQuery(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapIndexableContent(::Windows::Storage::Search::IndexableContent^ wintRtInstance);
  ::Windows::Storage::Search::IndexableContent^ UnwrapIndexableContent(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapQueryOptions(::Windows::Storage::Search::QueryOptions^ wintRtInstance);
  ::Windows::Storage::Search::QueryOptions^ UnwrapQueryOptions(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapIStorageQueryResultBase(::Windows::Storage::Search::IStorageQueryResultBase^ wintRtInstance);
  ::Windows::Storage::Search::IStorageQueryResultBase^ UnwrapIStorageQueryResultBase(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapIStorageFolderQueryOperations(::Windows::Storage::Search::IStorageFolderQueryOperations^ wintRtInstance);
  ::Windows::Storage::Search::IStorageFolderQueryOperations^ UnwrapIStorageFolderQueryOperations(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapStorageFileQueryResult(::Windows::Storage::Search::StorageFileQueryResult^ wintRtInstance);
  ::Windows::Storage::Search::StorageFileQueryResult^ UnwrapStorageFileQueryResult(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapStorageFolderQueryResult(::Windows::Storage::Search::StorageFolderQueryResult^ wintRtInstance);
  ::Windows::Storage::Search::StorageFolderQueryResult^ UnwrapStorageFolderQueryResult(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapStorageItemQueryResult(::Windows::Storage::Search::StorageItemQueryResult^ wintRtInstance);
  ::Windows::Storage::Search::StorageItemQueryResult^ UnwrapStorageItemQueryResult(Handle<Value> value);
  
  v8::Handle<v8::Value> WrapSortEntryVector(::Windows::Storage::Search::SortEntryVector^ wintRtInstance);
  ::Windows::Storage::Search::SortEntryVector^ UnwrapSortEntryVector(Handle<Value> value);
  


  static v8::Handle<v8::Value> InitDateStackOptionEnum(const Handle<Object> exports)
  {
    HandleScope scope;
    
    Handle<Object> enumObject = Object::New();
    exports->Set(String::NewSymbol("DateStackOption"), enumObject);

    enumObject->Set(String::NewSymbol("none"), Integer::New(0));
    enumObject->Set(String::NewSymbol("year"), Integer::New(1));
    enumObject->Set(String::NewSymbol("month"), Integer::New(2));

    return scope.Close(Undefined());
  }


  static v8::Handle<v8::Value> InitIndexerOptionEnum(const Handle<Object> exports)
  {
    HandleScope scope;
    
    Handle<Object> enumObject = Object::New();
    exports->Set(String::NewSymbol("IndexerOption"), enumObject);

    enumObject->Set(String::NewSymbol("useIndexerWhenAvailable"), Integer::New(0));
    enumObject->Set(String::NewSymbol("onlyUseIndexer"), Integer::New(1));
    enumObject->Set(String::NewSymbol("doNotUseIndexer"), Integer::New(2));

    return scope.Close(Undefined());
  }


  static v8::Handle<v8::Value> InitFolderDepthEnum(const Handle<Object> exports)
  {
    HandleScope scope;
    
    Handle<Object> enumObject = Object::New();
    exports->Set(String::NewSymbol("FolderDepth"), enumObject);

    enumObject->Set(String::NewSymbol("shallow"), Integer::New(0));
    enumObject->Set(String::NewSymbol("deep"), Integer::New(1));

    return scope.Close(Undefined());
  }


  static v8::Handle<v8::Value> InitCommonFileQueryEnum(const Handle<Object> exports)
  {
    HandleScope scope;
    
    Handle<Object> enumObject = Object::New();
    exports->Set(String::NewSymbol("CommonFileQuery"), enumObject);

    enumObject->Set(String::NewSymbol("defaultQuery"), Integer::New(0));
    enumObject->Set(String::NewSymbol("orderByName"), Integer::New(1));
    enumObject->Set(String::NewSymbol("orderByTitle"), Integer::New(2));
    enumObject->Set(String::NewSymbol("orderByMusicProperties"), Integer::New(3));
    enumObject->Set(String::NewSymbol("orderBySearchRank"), Integer::New(4));
    enumObject->Set(String::NewSymbol("orderByDate"), Integer::New(5));

    return scope.Close(Undefined());
  }


  static v8::Handle<v8::Value> InitCommonFolderQueryEnum(const Handle<Object> exports)
  {
    HandleScope scope;
    
    Handle<Object> enumObject = Object::New();
    exports->Set(String::NewSymbol("CommonFolderQuery"), enumObject);

    enumObject->Set(String::NewSymbol("defaultQuery"), Integer::New(0));
    enumObject->Set(String::NewSymbol("groupByYear"), Integer::New(1));
    enumObject->Set(String::NewSymbol("groupByMonth"), Integer::New(2));
    enumObject->Set(String::NewSymbol("groupByArtist"), Integer::New(3));
    enumObject->Set(String::NewSymbol("groupByAlbum"), Integer::New(4));
    enumObject->Set(String::NewSymbol("groupByAlbumArtist"), Integer::New(5));
    enumObject->Set(String::NewSymbol("groupByComposer"), Integer::New(6));
    enumObject->Set(String::NewSymbol("groupByGenre"), Integer::New(7));
    enumObject->Set(String::NewSymbol("groupByPublishedYear"), Integer::New(8));
    enumObject->Set(String::NewSymbol("groupByRating"), Integer::New(9));
    enumObject->Set(String::NewSymbol("groupByTag"), Integer::New(10));
    enumObject->Set(String::NewSymbol("groupByAuthor"), Integer::New(11));
    enumObject->Set(String::NewSymbol("groupByType"), Integer::New(12));

    return scope.Close(Undefined());
  }


  static v8::Handle<v8::Value> InitIndexedStateEnum(const Handle<Object> exports)
  {
    HandleScope scope;
    
    Handle<Object> enumObject = Object::New();
    exports->Set(String::NewSymbol("IndexedState"), enumObject);

    enumObject->Set(String::NewSymbol("unknown"), Integer::New(0));
    enumObject->Set(String::NewSymbol("notIndexed"), Integer::New(1));
    enumObject->Set(String::NewSymbol("partiallyIndexed"), Integer::New(2));
    enumObject->Set(String::NewSymbol("fullyIndexed"), Integer::New(3));

    return scope.Close(Undefined());
  }



  
  static bool IsSortEntryJsObject(Handle<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Handle<String> symbol;
    Handle<Object> obj = value.As<Object>();

    symbol = String::NewSymbol("propertyName");
    if (obj->Has(symbol))
    {
      if (!obj->Get(symbol)->IsString())
      {
          return false;
      }
    }
    
    symbol = String::NewSymbol("ascendingOrder");
    if (obj->Has(symbol))
    {
      if (!obj->Get(symbol)->IsBoolean())
      {
          return false;
      }
    }
    
    return true;
  }

  ::Windows::Storage::Search::SortEntry SortEntryFromJsObject(Handle<Value> value)
  {
    HandleScope scope;
    ::Windows::Storage::Search::SortEntry returnValue;
    
    if (!value->IsObject())
    {
      ThrowException(Exception::TypeError(NodeRT::Utils::NewString(L"Unexpected type, expected an object")));
      return returnValue;
    }

    Handle<Object> obj = value.As<Object>();
    Handle<String> symbol;

    symbol = String::NewSymbol("propertyName");
    if (obj->Has(symbol))
    {
      returnValue.PropertyName = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(obj->Get(symbol))));
    }
    
    symbol = String::NewSymbol("ascendingOrder");
    if (obj->Has(symbol))
    {
      returnValue.AscendingOrder = obj->Get(symbol)->BooleanValue();
    }
    
    return returnValue;
  }

  Handle<Value> SortEntryToJsObject(::Windows::Storage::Search::SortEntry value)
  {
    HandleScope scope;

    Handle<Object> obj = Object::New();

    obj->Set(String::NewSymbol("propertyName"), NodeRT::Utils::NewString(value.PropertyName->Data()));
    obj->Set(String::NewSymbol("ascendingOrder"), Boolean::New(value.AscendingOrder));
    
    return scope.Close(obj);
  }

  
  static bool IsTextSegmentJsObject(Handle<Value> value)
  {
    if (!value->IsObject())
    {
      return false;
    }

    Handle<String> symbol;
    Handle<Object> obj = value.As<Object>();

    symbol = String::NewSymbol("startPosition");
    if (obj->Has(symbol))
    {
      if (!obj->Get(symbol)->IsUint32())
      {
          return false;
      }
    }
    
    symbol = String::NewSymbol("length");
    if (obj->Has(symbol))
    {
      if (!obj->Get(symbol)->IsUint32())
      {
          return false;
      }
    }
    
    return true;
  }

  ::Windows::Data::Text::TextSegment TextSegmentFromJsObject(Handle<Value> value)
  {
    HandleScope scope;
    ::Windows::Data::Text::TextSegment returnValue;
    
    if (!value->IsObject())
    {
      ThrowException(Exception::TypeError(NodeRT::Utils::NewString(L"Unexpected type, expected an object")));
      return returnValue;
    }

    Handle<Object> obj = value.As<Object>();
    Handle<String> symbol;

    symbol = String::NewSymbol("startPosition");
    if (obj->Has(symbol))
    {
      returnValue.StartPosition = static_cast<unsigned int>(obj->Get(symbol)->IntegerValue());
    }
    
    symbol = String::NewSymbol("length");
    if (obj->Has(symbol))
    {
      returnValue.Length = static_cast<unsigned int>(obj->Get(symbol)->IntegerValue());
    }
    
    return returnValue;
  }

  Handle<Value> TextSegmentToJsObject(::Windows::Data::Text::TextSegment value)
  {
    HandleScope scope;

    Handle<Object> obj = Object::New();

    obj->Set(String::NewSymbol("startPosition"), Integer::New(value.StartPosition));
    obj->Set(String::NewSymbol("length"), Integer::New(value.Length));
    
    return scope.Close(obj);
  }

  
  class ContentIndexer : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("ContentIndexer"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
      Handle<Value> asyncSymbol = String::NewSymbol("__winRtAsync__");
      Handle<Function> func;
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("createQuery"), FunctionTemplate::New(CreateQuery)->GetFunction());
      
            
      func = FunctionTemplate::New(AddAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("addAsync"), func);
      func = FunctionTemplate::New(UpdateAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("updateAsync"), func);
      func = FunctionTemplate::New(DeleteAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("deleteAsync"), func);
      func = FunctionTemplate::New(DeleteMultipleAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("deleteMultipleAsync"), func);
      func = FunctionTemplate::New(DeleteAllAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("deleteAllAsync"), func);
      func = FunctionTemplate::New(RetrievePropertiesAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("retrievePropertiesAsync"), func);
      
                  
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("revision"), RevisionGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();

      constructor->Set(String::NewSymbol("getIndexer"), FunctionTemplate::New(GetIndexer)->GetFunction());

      exports->Set(String::NewSymbol("ContentIndexer"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ContentIndexer(::Windows::Storage::Search::ContentIndexer^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::ContentIndexer^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::ContentIndexer^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      ContentIndexer *wrapperInstance = new ContentIndexer(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


    static Handle<Value> AddAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(args.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (args.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::IIndexableContent^ arg0 = UnwrapIIndexableContent(args[0]);
          
          op = wrapper->_instance->AddAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Handle<Value> args[] = {Undefined()};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> UpdateAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(args.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (args.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::IIndexableContent^ arg0 = UnwrapIIndexableContent(args[0]);
          
          op = wrapper->_instance->UpdateAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Handle<Value> args[] = {Undefined()};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> DeleteAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(args.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (args.Length() == 2
        && args[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[0])));
          
          op = wrapper->_instance->DeleteAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Handle<Value> args[] = {Undefined()};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> DeleteMultipleAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(args.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (args.Length() == 2
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(args[0]) || args[0]->IsArray()))
      {
        try
        {
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg0 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Handle<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[0]);
          
          op = wrapper->_instance->DeleteMultipleAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Handle<Value> args[] = {Undefined()};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> DeleteAllAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(args.This());

      ::Windows::Foundation::IAsyncAction^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->DeleteAllAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<void> t) 
      {	
        try
        {
          t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            Handle<Value> args[] = {Undefined()};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> RetrievePropertiesAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^>^ op;
    

      if (args.Length() == 3
        && args[0]->IsString()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(args[1]) || args[1]->IsArray()))
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[0])));
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg1 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Handle<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[1]);
          
          op = wrapper->_instance->RetrievePropertiesAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::MapViewWrapper<::Platform::String^,::Platform::Object^>::CreateMapViewWrapper(result, 
            [](::Platform::String^ val) -> Handle<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Handle<Value> value) -> bool {
              return value->IsString();
            },
            [](Handle<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            },
            [](::Platform::Object^ val) -> Handle<Value> {
              return CreateOpaqueWrapper(val);
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
  
    static Handle<Value> CreateQuery(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(args.This());

      if (args.Length() == 4
        && args[0]->IsString()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(args[1]) || args[1]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^>(args[2]) || args[2]->IsArray())
        && args[3]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[0])));
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg1 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Handle<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[1]);
          ::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^ arg2 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Storage::Search::SortEntry>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return IsSortEntryJsObject(value);
                 },
                 [](Handle<Value> value) -> ::Windows::Storage::Search::SortEntry {
                   return SortEntryFromJsObject(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[2]);
          Platform::String^ arg3 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[3])));
          
          ::Windows::Storage::Search::ContentIndexerQuery^ result;
          result = wrapper->_instance->CreateQuery(arg0, arg1, arg2, arg3);
          return scope.Close(WrapContentIndexerQuery(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 3
        && args[0]->IsString()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(args[1]) || args[1]->IsArray())
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^>(args[2]) || args[2]->IsArray()))
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[0])));
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg1 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Handle<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[1]);
          ::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^ arg2 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Windows::Storage::Search::SortEntry>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return IsSortEntryJsObject(value);
                 },
                 [](Handle<Value> value) -> ::Windows::Storage::Search::SortEntry {
                   return SortEntryFromJsObject(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Windows::Storage::Search::SortEntry>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[2]);
          
          ::Windows::Storage::Search::ContentIndexerQuery^ result;
          result = wrapper->_instance->CreateQuery(arg0, arg1, arg2);
          return scope.Close(WrapContentIndexerQuery(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 2
        && args[0]->IsString()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(args[1]) || args[1]->IsArray()))
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[0])));
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg1 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Handle<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[1]);
          
          ::Windows::Storage::Search::ContentIndexerQuery^ result;
          result = wrapper->_instance->CreateQuery(arg0, arg1);
          return scope.Close(WrapContentIndexerQuery(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }


    static Handle<Value> GetIndexer(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() == 1
        && args[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[0])));
          
          ::Windows::Storage::Search::ContentIndexer^ result;
          result = ::Windows::Storage::Search::ContentIndexer::GetIndexer(arg0);
          return scope.Close(WrapContentIndexer(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::ContentIndexer^ result;
          result = ::Windows::Storage::Search::ContentIndexer::GetIndexer();
          return scope.Close(WrapContentIndexer(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }

    static Handle<Value> RevisionGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexer^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      ContentIndexer *wrapper = ContentIndexer::Unwrap<ContentIndexer>(info.This());

      try 
      {
        unsigned __int64 result = wrapper->_instance->Revision;
        return scope.Close(Number::New(static_cast<double>(result)));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


  private:
    ::Windows::Storage::Search::ContentIndexer^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapContentIndexer(::Windows::Storage::Search::ContentIndexer^ wintRtInstance);
    friend ::Windows::Storage::Search::ContentIndexer^ UnwrapContentIndexer(Handle<Value> value);
    friend bool IsContentIndexerWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> ContentIndexer::s_constructorTemplate;

  v8::Handle<v8::Value> WrapContentIndexer(::Windows::Storage::Search::ContentIndexer^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(ContentIndexer::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::ContentIndexer^ UnwrapContentIndexer(Handle<Value> value)
  {
     return ContentIndexer::Unwrap<ContentIndexer>(value.As<Object>())->_instance;
  }

  void InitContentIndexer(Handle<Object> exports)
  {
    ContentIndexer::Init(exports);
  }

  class IIndexableContent : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("IIndexableContent"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("id"), IdGetter, IdSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("properties"), PropertiesGetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("stream"), StreamGetter, StreamSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("streamContentType"), StreamContentTypeGetter, StreamContentTypeSetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("IIndexableContent"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IIndexableContent(::Windows::Storage::Search::IIndexableContent^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::IIndexableContent^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::IIndexableContent^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      IIndexableContent *wrapperInstance = new IIndexableContent(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


  



    static Handle<Value> IdGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IIndexableContent *wrapper = IIndexableContent::Unwrap<IIndexableContent>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->Id;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void IdSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(info.This()))
      {
        return;
      }

      IIndexableContent *wrapper = IIndexableContent::Unwrap<IIndexableContent>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->Id = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> PropertiesGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IIndexableContent *wrapper = IIndexableContent::Unwrap<IIndexableContent>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IMap<::Platform::String^, ::Platform::Object^>^ result = wrapper->_instance->Properties;
        return scope.Close(NodeRT::Collections::MapWrapper<::Platform::String^,::Platform::Object^>::CreateMapWrapper(result, 
            [](::Platform::String^ val) -> Handle<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Handle<Value> value) -> bool {
              return value->IsString();
            },
            [](Handle<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            },
            [](::Platform::Object^ val) -> Handle<Value> {
              return CreateOpaqueWrapper(val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(value);
            },
            [](Handle<Value> value) -> ::Platform::Object^ {
              return dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(value));
            }
          ));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static Handle<Value> StreamGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IIndexableContent *wrapper = IIndexableContent::Unwrap<IIndexableContent>(info.This());

      try 
      {
        ::Windows::Storage::Streams::IRandomAccessStream^ result = wrapper->_instance->Stream;
        return scope.Close(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IRandomAccessStream", result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void StreamSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IRandomAccessStream^>(value))
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(info.This()))
      {
        return;
      }

      IIndexableContent *wrapper = IIndexableContent::Unwrap<IIndexableContent>(info.This());

      try 
      {
        
        ::Windows::Storage::Streams::IRandomAccessStream^ winRtValue = dynamic_cast<::Windows::Storage::Streams::IRandomAccessStream^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Stream = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> StreamContentTypeGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IIndexableContent *wrapper = IIndexableContent::Unwrap<IIndexableContent>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->StreamContentType;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void StreamContentTypeSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(info.This()))
      {
        return;
      }

      IIndexableContent *wrapper = IIndexableContent::Unwrap<IIndexableContent>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->StreamContentType = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Storage::Search::IIndexableContent^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapIIndexableContent(::Windows::Storage::Search::IIndexableContent^ wintRtInstance);
    friend ::Windows::Storage::Search::IIndexableContent^ UnwrapIIndexableContent(Handle<Value> value);
    friend bool IsIIndexableContentWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> IIndexableContent::s_constructorTemplate;

  v8::Handle<v8::Value> WrapIIndexableContent(::Windows::Storage::Search::IIndexableContent^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(IIndexableContent::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::IIndexableContent^ UnwrapIIndexableContent(Handle<Value> value)
  {
     return IIndexableContent::Unwrap<IIndexableContent>(value.As<Object>())->_instance;
  }

  void InitIIndexableContent(Handle<Object> exports)
  {
    IIndexableContent::Init(exports);
  }

  class ValueAndLanguage : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("ValueAndLanguage"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("value"), ValueGetter, ValueSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("language"), LanguageGetter, LanguageSetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("ValueAndLanguage"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ValueAndLanguage(::Windows::Storage::Search::ValueAndLanguage^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::ValueAndLanguage^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ValueAndLanguage^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::ValueAndLanguage^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Storage::Search::ValueAndLanguage();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      ValueAndLanguage *wrapperInstance = new ValueAndLanguage(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


  



    static Handle<Value> ValueGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ValueAndLanguage^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      ValueAndLanguage *wrapper = ValueAndLanguage::Unwrap<ValueAndLanguage>(info.This());

      try 
      {
        ::Platform::Object^ result = wrapper->_instance->Value;
        return scope.Close(CreateOpaqueWrapper(result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void ValueSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(value))
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ValueAndLanguage^>(info.This()))
      {
        return;
      }

      ValueAndLanguage *wrapper = ValueAndLanguage::Unwrap<ValueAndLanguage>(info.This());

      try 
      {
        
        ::Platform::Object^ winRtValue = dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Value = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> LanguageGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ValueAndLanguage^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      ValueAndLanguage *wrapper = ValueAndLanguage::Unwrap<ValueAndLanguage>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->Language;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void LanguageSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ValueAndLanguage^>(info.This()))
      {
        return;
      }

      ValueAndLanguage *wrapper = ValueAndLanguage::Unwrap<ValueAndLanguage>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->Language = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    


  private:
    ::Windows::Storage::Search::ValueAndLanguage^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapValueAndLanguage(::Windows::Storage::Search::ValueAndLanguage^ wintRtInstance);
    friend ::Windows::Storage::Search::ValueAndLanguage^ UnwrapValueAndLanguage(Handle<Value> value);
    friend bool IsValueAndLanguageWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> ValueAndLanguage::s_constructorTemplate;

  v8::Handle<v8::Value> WrapValueAndLanguage(::Windows::Storage::Search::ValueAndLanguage^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(ValueAndLanguage::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::ValueAndLanguage^ UnwrapValueAndLanguage(Handle<Value> value)
  {
     return ValueAndLanguage::Unwrap<ValueAndLanguage>(value.As<Object>())->_instance;
  }

  void InitValueAndLanguage(Handle<Object> exports)
  {
    ValueAndLanguage::Init(exports);
  }

  class ContentIndexerQuery : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("ContentIndexerQuery"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
      Handle<Value> asyncSymbol = String::NewSymbol("__winRtAsync__");
      Handle<Function> func;
                  
      func = FunctionTemplate::New(GetCountAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getCountAsync"), func);
      func = FunctionTemplate::New(GetPropertiesAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getPropertiesAsync"), func);
      func = FunctionTemplate::New(GetAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getAsync"), func);
      
                  
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("queryFolder"), QueryFolderGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("ContentIndexerQuery"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    ContentIndexerQuery(::Windows::Storage::Search::ContentIndexerQuery^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::ContentIndexerQuery^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexerQuery^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::ContentIndexerQuery^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      ContentIndexerQuery *wrapperInstance = new ContentIndexerQuery(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


    static Handle<Value> GetCountAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexerQuery^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexerQuery *wrapper = ContentIndexerQuery::Unwrap<ContentIndexerQuery>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetCountAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetPropertiesAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexerQuery^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexerQuery *wrapper = ContentIndexerQuery::Unwrap<ContentIndexerQuery>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^>^>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetPropertiesAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 3
        && args[0]->IsUint32()
        && args[1]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          
          op = wrapper->_instance->GetPropertiesAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^>::CreateVectorViewWrapper(result, 
            [](::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^ val) -> Handle<Value> {
              return NodeRT::Collections::MapViewWrapper<::Platform::String^,::Platform::Object^>::CreateMapViewWrapper(val, 
            [](::Platform::String^ val) -> Handle<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Handle<Value> value) -> bool {
              return value->IsString();
            },
            [](Handle<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            },
            [](::Platform::Object^ val) -> Handle<Value> {
              return CreateOpaqueWrapper(val);
            }
          );
            },
            [](Handle<Value> value) -> bool {
              return (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^>(value) || value->IsObject());
            },
            [](Handle<Value> value) -> ::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^ {
              return 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^
            {
              if (value->IsObject())
              {
                return NodeRT::Collections::JsObjectToWinrtMapView<::Platform::Object^>(value.As<Object>(), 
                 [](Handle<Value> value) -> bool {
                   return NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(value);
                 },
                 [](Handle<Value> value) -> ::Platform::Object^ {
                   return dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(value));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IMapView<::Platform::String^, ::Platform::Object^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (value);
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexerQuery^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      ContentIndexerQuery *wrapper = ContentIndexerQuery::Unwrap<ContentIndexerQuery>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::Search::IIndexableContent^>^>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 3
        && args[0]->IsUint32()
        && args[1]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          
          op = wrapper->_instance->GetAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::Search::IIndexableContent^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Storage::Search::IIndexableContent^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::Search::IIndexableContent^ val) -> Handle<Value> {
              return WrapIIndexableContent(val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IIndexableContent^>(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::Search::IIndexableContent^ {
              return UnwrapIIndexableContent(value);
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
  



    static Handle<Value> QueryFolderGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::ContentIndexerQuery^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      ContentIndexerQuery *wrapper = ContentIndexerQuery::Unwrap<ContentIndexerQuery>(info.This());

      try 
      {
        ::Windows::Storage::StorageFolder^ result = wrapper->_instance->QueryFolder;
        return scope.Close(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


  private:
    ::Windows::Storage::Search::ContentIndexerQuery^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapContentIndexerQuery(::Windows::Storage::Search::ContentIndexerQuery^ wintRtInstance);
    friend ::Windows::Storage::Search::ContentIndexerQuery^ UnwrapContentIndexerQuery(Handle<Value> value);
    friend bool IsContentIndexerQueryWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> ContentIndexerQuery::s_constructorTemplate;

  v8::Handle<v8::Value> WrapContentIndexerQuery(::Windows::Storage::Search::ContentIndexerQuery^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(ContentIndexerQuery::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::ContentIndexerQuery^ UnwrapContentIndexerQuery(Handle<Value> value)
  {
     return ContentIndexerQuery::Unwrap<ContentIndexerQuery>(value.As<Object>())->_instance;
  }

  void InitContentIndexerQuery(Handle<Object> exports)
  {
    ContentIndexerQuery::Init(exports);
  }

  class IndexableContent : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("IndexableContent"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
                              
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("streamContentType"), StreamContentTypeGetter, StreamContentTypeSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("stream"), StreamGetter, StreamSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("id"), IdGetter, IdSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("properties"), PropertiesGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("IndexableContent"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IndexableContent(::Windows::Storage::Search::IndexableContent^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::IndexableContent^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::IndexableContent^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Storage::Search::IndexableContent();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      IndexableContent *wrapperInstance = new IndexableContent(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


  



    static Handle<Value> StreamContentTypeGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IndexableContent *wrapper = IndexableContent::Unwrap<IndexableContent>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->StreamContentType;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void StreamContentTypeSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(info.This()))
      {
        return;
      }

      IndexableContent *wrapper = IndexableContent::Unwrap<IndexableContent>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->StreamContentType = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> StreamGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IndexableContent *wrapper = IndexableContent::Unwrap<IndexableContent>(info.This());

      try 
      {
        ::Windows::Storage::Streams::IRandomAccessStream^ result = wrapper->_instance->Stream;
        return scope.Close(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage.Streams", "IRandomAccessStream", result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void StreamSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Streams::IRandomAccessStream^>(value))
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(info.This()))
      {
        return;
      }

      IndexableContent *wrapper = IndexableContent::Unwrap<IndexableContent>(info.This());

      try 
      {
        
        ::Windows::Storage::Streams::IRandomAccessStream^ winRtValue = dynamic_cast<::Windows::Storage::Streams::IRandomAccessStream^>(NodeRT::Utils::GetObjectInstance(value));

        wrapper->_instance->Stream = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> IdGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IndexableContent *wrapper = IndexableContent::Unwrap<IndexableContent>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->Id;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void IdSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(info.This()))
      {
        return;
      }

      IndexableContent *wrapper = IndexableContent::Unwrap<IndexableContent>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->Id = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> PropertiesGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IndexableContent^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IndexableContent *wrapper = IndexableContent::Unwrap<IndexableContent>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IMap<::Platform::String^, ::Platform::Object^>^ result = wrapper->_instance->Properties;
        return scope.Close(NodeRT::Collections::MapWrapper<::Platform::String^,::Platform::Object^>::CreateMapWrapper(result, 
            [](::Platform::String^ val) -> Handle<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Handle<Value> value) -> bool {
              return value->IsString();
            },
            [](Handle<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            },
            [](::Platform::Object^ val) -> Handle<Value> {
              return CreateOpaqueWrapper(val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(value);
            },
            [](Handle<Value> value) -> ::Platform::Object^ {
              return dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(value));
            }
          ));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


  private:
    ::Windows::Storage::Search::IndexableContent^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapIndexableContent(::Windows::Storage::Search::IndexableContent^ wintRtInstance);
    friend ::Windows::Storage::Search::IndexableContent^ UnwrapIndexableContent(Handle<Value> value);
    friend bool IsIndexableContentWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> IndexableContent::s_constructorTemplate;

  v8::Handle<v8::Value> WrapIndexableContent(::Windows::Storage::Search::IndexableContent^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(IndexableContent::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::IndexableContent^ UnwrapIndexableContent(Handle<Value> value)
  {
     return IndexableContent::Unwrap<IndexableContent>(value.As<Object>())->_instance;
  }

  void InitIndexableContent(Handle<Object> exports)
  {
    IndexableContent::Init(exports);
  }

  class QueryOptions : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("QueryOptions"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("saveToString"), FunctionTemplate::New(SaveToString)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("loadFromString"), FunctionTemplate::New(LoadFromString)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("setThumbnailPrefetch"), FunctionTemplate::New(SetThumbnailPrefetch)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("setPropertyPrefetch"), FunctionTemplate::New(SetPropertyPrefetch)->GetFunction());
      
                        
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("userSearchFilter"), UserSearchFilterGetter, UserSearchFilterSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("language"), LanguageGetter, LanguageSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("indexerOption"), IndexerOptionGetter, IndexerOptionSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("folderDepth"), FolderDepthGetter, FolderDepthSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("applicationSearchFilter"), ApplicationSearchFilterGetter, ApplicationSearchFilterSetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("dateStackOption"), DateStackOptionGetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("fileTypeFilter"), FileTypeFilterGetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("groupPropertyName"), GroupPropertyNameGetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("sortOrder"), SortOrderGetter);
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("storageProviderIdFilter"), StorageProviderIdFilterGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("QueryOptions"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    QueryOptions(::Windows::Storage::Search::QueryOptions^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::QueryOptions^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::QueryOptions^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 2
        && args[0]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(args[1]) || args[1]->IsArray()))
      {
        try
        {
          ::Windows::Storage::Search::CommonFileQuery arg0 = static_cast<::Windows::Storage::Search::CommonFileQuery>(args[0]->Int32Value());
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg1 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Handle<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[1]);
          
          winRtInstance = ref new ::Windows::Storage::Search::QueryOptions(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 1
        && args[0]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFolderQuery arg0 = static_cast<::Windows::Storage::Search::CommonFolderQuery>(args[0]->Int32Value());
          
          winRtInstance = ref new ::Windows::Storage::Search::QueryOptions(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 0)
      {
        try
        {
          winRtInstance = ref new ::Windows::Storage::Search::QueryOptions();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      QueryOptions *wrapperInstance = new QueryOptions(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


  
    static Handle<Value> SaveToString(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          Platform::String^ result;
          result = wrapper->_instance->SaveToString();
          return scope.Close(NodeRT::Utils::NewString(result->Data()));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> LoadFromString(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(args.This());

      if (args.Length() == 1
        && args[0]->IsString())
      {
        try
        {
          Platform::String^ arg0 = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(args[0])));
          
          wrapper->_instance->LoadFromString(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> SetThumbnailPrefetch(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(args.This());

      if (args.Length() == 3
        && args[0]->IsInt32()
        && args[1]->IsUint32()
        && args[2]->IsInt32())
      {
        try
        {
          ::Windows::Storage::FileProperties::ThumbnailMode arg0 = static_cast<::Windows::Storage::FileProperties::ThumbnailMode>(args[0]->Int32Value());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          ::Windows::Storage::FileProperties::ThumbnailOptions arg2 = static_cast<::Windows::Storage::FileProperties::ThumbnailOptions>(args[2]->Int32Value());
          
          wrapper->_instance->SetThumbnailPrefetch(arg0, arg1, arg2);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> SetPropertyPrefetch(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(args.This());

      if (args.Length() == 2
        && args[0]->IsInt32()
        && (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(args[1]) || args[1]->IsArray()))
      {
        try
        {
          ::Windows::Storage::FileProperties::PropertyPrefetchOptions arg0 = static_cast<::Windows::Storage::FileProperties::PropertyPrefetchOptions>(args[0]->Int32Value());
          ::Windows::Foundation::Collections::IIterable<::Platform::String^>^ arg1 = 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IIterable<::Platform::String^>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVector<::Platform::String^>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return (!NodeRT::Utils::IsWinRtWrapper(value));
                 },
                 [](Handle<Value> value) -> ::Platform::String^ {
                   return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IIterable<::Platform::String^>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[1]);
          
          wrapper->_instance->SetPropertyPrefetch(arg0, arg1);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }



    static Handle<Value> UserSearchFilterGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->UserSearchFilter;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void UserSearchFilterSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return;
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->UserSearchFilter = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> LanguageGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->Language;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void LanguageSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return;
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->Language = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> IndexerOptionGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        ::Windows::Storage::Search::IndexerOption result = wrapper->_instance->IndexerOption;
        return scope.Close(Integer::New(static_cast<int>(result)));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void IndexerOptionSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return;
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        
        ::Windows::Storage::Search::IndexerOption winRtValue = static_cast<::Windows::Storage::Search::IndexerOption>(value->Int32Value());

        wrapper->_instance->IndexerOption = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> FolderDepthGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        ::Windows::Storage::Search::FolderDepth result = wrapper->_instance->FolderDepth;
        return scope.Close(Integer::New(static_cast<int>(result)));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void FolderDepthSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsInt32())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return;
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        
        ::Windows::Storage::Search::FolderDepth winRtValue = static_cast<::Windows::Storage::Search::FolderDepth>(value->Int32Value());

        wrapper->_instance->FolderDepth = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> ApplicationSearchFilterGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->ApplicationSearchFilter;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static void ApplicationSearchFilterSetter(Local<String> property, Local<Value> value, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!value->IsString())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Value to set is of unexpected type")));
        return;
      }

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return;
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        
        Platform::String^ winRtValue = ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));

        wrapper->_instance->ApplicationSearchFilter = winRtValue;
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }
    }
    
    static Handle<Value> DateStackOptionGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        ::Windows::Storage::Search::DateStackOption result = wrapper->_instance->DateStackOption;
        return scope.Close(Integer::New(static_cast<int>(result)));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static Handle<Value> FileTypeFilterGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVector<::Platform::String^>^ result = wrapper->_instance->FileTypeFilter;
        return scope.Close(NodeRT::Collections::VectorWrapper<::Platform::String^>::CreateVectorWrapper(result, 
            [](::Platform::String^ val) -> Handle<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Handle<Value> value) -> bool {
              return value->IsString();
            },
            [](Handle<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static Handle<Value> GroupPropertyNameGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        Platform::String^ result = wrapper->_instance->GroupPropertyName;
        return scope.Close(NodeRT::Utils::NewString(result->Data()));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static Handle<Value> SortOrderGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVector<::Windows::Storage::Search::SortEntry>^ result = wrapper->_instance->SortOrder;
        return scope.Close(NodeRT::Collections::VectorWrapper<::Windows::Storage::Search::SortEntry>::CreateVectorWrapper(result, 
            [](::Windows::Storage::Search::SortEntry val) -> Handle<Value> {
              return SortEntryToJsObject(val);
            },
            [](Handle<Value> value) -> bool {
              return IsSortEntryJsObject(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::Search::SortEntry {
              return SortEntryFromJsObject(value);
            }
          ));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    
    static Handle<Value> StorageProviderIdFilterGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      QueryOptions *wrapper = QueryOptions::Unwrap<QueryOptions>(info.This());

      try 
      {
        ::Windows::Foundation::Collections::IVector<::Platform::String^>^ result = wrapper->_instance->StorageProviderIdFilter;
        return scope.Close(NodeRT::Collections::VectorWrapper<::Platform::String^>::CreateVectorWrapper(result, 
            [](::Platform::String^ val) -> Handle<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Handle<Value> value) -> bool {
              return value->IsString();
            },
            [](Handle<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            }
          ));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


  private:
    ::Windows::Storage::Search::QueryOptions^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapQueryOptions(::Windows::Storage::Search::QueryOptions^ wintRtInstance);
    friend ::Windows::Storage::Search::QueryOptions^ UnwrapQueryOptions(Handle<Value> value);
    friend bool IsQueryOptionsWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> QueryOptions::s_constructorTemplate;

  v8::Handle<v8::Value> WrapQueryOptions(::Windows::Storage::Search::QueryOptions^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(QueryOptions::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::QueryOptions^ UnwrapQueryOptions(Handle<Value> value)
  {
     return QueryOptions::Unwrap<QueryOptions>(value.As<Object>())->_instance;
  }

  void InitQueryOptions(Handle<Object> exports)
  {
    QueryOptions::Init(exports);
  }

  class IStorageQueryResultBase : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("IStorageQueryResultBase"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
      Handle<Value> asyncSymbol = String::NewSymbol("__winRtAsync__");
      Handle<Function> func;
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getCurrentQueryOptions"), FunctionTemplate::New(GetCurrentQueryOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("applyNewQueryOptions"), FunctionTemplate::New(ApplyNewQueryOptions)->GetFunction());
      
            
      func = FunctionTemplate::New(GetItemCountAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getItemCountAsync"), func);
      func = FunctionTemplate::New(FindStartIndexAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("findStartIndexAsync"), func);
      
            
      Local<Function> addListenerFunc = FunctionTemplate::New(AddListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("addListener"), addListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("on"), addListenerFunc);
      Local<Function> removeListenerFunc = FunctionTemplate::New(RemoveListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("removeListener"), removeListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("off"), removeListenerFunc);
            
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("folder"), FolderGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("IStorageQueryResultBase"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IStorageQueryResultBase(::Windows::Storage::Search::IStorageQueryResultBase^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::IStorageQueryResultBase^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::IStorageQueryResultBase^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      IStorageQueryResultBase *wrapperInstance = new IStorageQueryResultBase(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


    static Handle<Value> GetItemCountAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetItemCountAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> FindStartIndexAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(args[0]))
      {
        try
        {
          ::Platform::Object^ arg0 = dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(args[0]));
          
          op = wrapper->_instance->FindStartIndexAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
  
    static Handle<Value> GetCurrentQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ result;
          result = wrapper->_instance->GetCurrentQueryOptions();
          return scope.Close(WrapQueryOptions(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> ApplyNewQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          wrapper->_instance->ApplyNewQueryOptions(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }



    static Handle<Value> FolderGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(info.This());

      try 
      {
        ::Windows::Storage::StorageFolder^ result = wrapper->_instance->Folder;
        return scope.Close(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


    static v8::Handle<v8::Value> AddListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected arguments are eventName(string),callback(function)")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;
      
      Local<Function> callback = args[1].As<Function>();
      
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->ContentsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->OptionsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else 
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
          tokenMap = Object::New();
          callback->SetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME), tokenMap);
      }

      tokenMap.As<Object>()->Set(args[1], CreateOpaqueWrapper(::Windows::Foundation::PropertyValue::CreateInt64(registrationToken.Value)));
                
      return scope.Close(Undefined());
    }

    static v8::Handle<v8::Value> RemoveListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected a string and a callback")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;

      if ((NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str)))
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Function> callback = args[1].As<Function>();
      Handle<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      Handle<Value> opaqueWrapperObj =  tokenMap.As<Object>()->Get(args[1]);

      if (opaqueWrapperObj.IsEmpty() || opaqueWrapperObj->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      OpaqueWrapper *opaqueWrapper = OpaqueWrapper::Unwrap<OpaqueWrapper>(opaqueWrapperObj.As<Object>());
            
      long long tokenValue = (long long) opaqueWrapper->GetObjectInstance();
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      registrationToken.Value = tokenValue;
        
      try 
      {
        if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());
          wrapper->_instance->ContentsChanged::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageQueryResultBase^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          IStorageQueryResultBase *wrapper = IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(args.This());
          wrapper->_instance->OptionsChanged::remove(registrationToken);
        }
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }

      tokenMap.As<Object>()->Delete(args[0].As<String>());

      return scope.Close(Undefined());
    }
  private:
    ::Windows::Storage::Search::IStorageQueryResultBase^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapIStorageQueryResultBase(::Windows::Storage::Search::IStorageQueryResultBase^ wintRtInstance);
    friend ::Windows::Storage::Search::IStorageQueryResultBase^ UnwrapIStorageQueryResultBase(Handle<Value> value);
    friend bool IsIStorageQueryResultBaseWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> IStorageQueryResultBase::s_constructorTemplate;

  v8::Handle<v8::Value> WrapIStorageQueryResultBase(::Windows::Storage::Search::IStorageQueryResultBase^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(IStorageQueryResultBase::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::IStorageQueryResultBase^ UnwrapIStorageQueryResultBase(Handle<Value> value)
  {
     return IStorageQueryResultBase::Unwrap<IStorageQueryResultBase>(value.As<Object>())->_instance;
  }

  void InitIStorageQueryResultBase(Handle<Object> exports)
  {
    IStorageQueryResultBase::Init(exports);
  }

  class IStorageFolderQueryOperations : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("IStorageFolderQueryOperations"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
      Handle<Value> asyncSymbol = String::NewSymbol("__winRtAsync__");
      Handle<Function> func;
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("createFileQuery"), FunctionTemplate::New(CreateFileQuery)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("createFileQueryWithOptions"), FunctionTemplate::New(CreateFileQueryWithOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("createFolderQuery"), FunctionTemplate::New(CreateFolderQuery)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("createFolderQueryWithOptions"), FunctionTemplate::New(CreateFolderQueryWithOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("createItemQuery"), FunctionTemplate::New(CreateItemQuery)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("createItemQueryWithOptions"), FunctionTemplate::New(CreateItemQueryWithOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("areQueryOptionsSupported"), FunctionTemplate::New(AreQueryOptionsSupported)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("isCommonFolderQuerySupported"), FunctionTemplate::New(IsCommonFolderQuerySupported)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("isCommonFileQuerySupported"), FunctionTemplate::New(IsCommonFileQuerySupported)->GetFunction());
      
            
      func = FunctionTemplate::New(GetIndexedStateAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getIndexedStateAsync"), func);
      func = FunctionTemplate::New(GetFilesAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getFilesAsync"), func);
      func = FunctionTemplate::New(GetFoldersAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getFoldersAsync"), func);
      func = FunctionTemplate::New(GetItemsAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getItemsAsync"), func);
      
                  
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("IStorageFolderQueryOperations"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    IStorageFolderQueryOperations(::Windows::Storage::Search::IStorageFolderQueryOperations^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::IStorageFolderQueryOperations^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::IStorageFolderQueryOperations^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      IStorageFolderQueryOperations *wrapperInstance = new IStorageFolderQueryOperations(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


    static Handle<Value> GetIndexedStateAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Storage::Search::IndexedState>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetIndexedStateAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Storage::Search::IndexedState> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(static_cast<int>(result));
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetFilesAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFile^>^>^ op;
    

      if (args.Length() == 4
        && args[0]->IsInt32()
        && args[1]->IsUint32()
        && args[2]->IsUint32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFileQuery arg0 = static_cast<::Windows::Storage::Search::CommonFileQuery>(args[0]->Int32Value());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          unsigned int arg2 = static_cast<unsigned int>(args[2]->IntegerValue());
          
          op = wrapper->_instance->GetFilesAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 2
        && args[0]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFileQuery arg0 = static_cast<::Windows::Storage::Search::CommonFileQuery>(args[0]->Int32Value());
          
          op = wrapper->_instance->GetFilesAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFile^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Storage::StorageFile^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::StorageFile^ val) -> Handle<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFile", val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFile^>(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::StorageFile^ {
              return dynamic_cast<::Windows::Storage::StorageFile^>(NodeRT::Utils::GetObjectInstance(value));
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetFoldersAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFolder^>^>^ op;
    

      if (args.Length() == 4
        && args[0]->IsInt32()
        && args[1]->IsUint32()
        && args[2]->IsUint32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFolderQuery arg0 = static_cast<::Windows::Storage::Search::CommonFolderQuery>(args[0]->Int32Value());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          unsigned int arg2 = static_cast<unsigned int>(args[2]->IntegerValue());
          
          op = wrapper->_instance->GetFoldersAsync(arg0,arg1,arg2);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 2
        && args[0]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFolderQuery arg0 = static_cast<::Windows::Storage::Search::CommonFolderQuery>(args[0]->Int32Value());
          
          op = wrapper->_instance->GetFoldersAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFolder^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Storage::StorageFolder^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::StorageFolder^ val) -> Handle<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFolder^>(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::StorageFolder^ {
              return dynamic_cast<::Windows::Storage::StorageFolder^>(NodeRT::Utils::GetObjectInstance(value));
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetItemsAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::IStorageItem^>^>^ op;
    

      if (args.Length() == 3
        && args[0]->IsUint32()
        && args[1]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          
          op = wrapper->_instance->GetItemsAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::IStorageItem^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Storage::IStorageItem^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::IStorageItem^ val) -> Handle<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "IStorageItem", val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::IStorageItem^>(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::IStorageItem^ {
              return dynamic_cast<::Windows::Storage::IStorageItem^>(NodeRT::Utils::GetObjectInstance(value));
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
  
    static Handle<Value> CreateFileQuery(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::StorageFileQueryResult^ result;
          result = wrapper->_instance->CreateFileQuery();
          return scope.Close(WrapStorageFileQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 1
        && args[0]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFileQuery arg0 = static_cast<::Windows::Storage::Search::CommonFileQuery>(args[0]->Int32Value());
          
          ::Windows::Storage::Search::StorageFileQueryResult^ result;
          result = wrapper->_instance->CreateFileQuery(arg0);
          return scope.Close(WrapStorageFileQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> CreateFileQueryWithOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          ::Windows::Storage::Search::StorageFileQueryResult^ result;
          result = wrapper->_instance->CreateFileQueryWithOptions(arg0);
          return scope.Close(WrapStorageFileQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> CreateFolderQuery(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::StorageFolderQueryResult^ result;
          result = wrapper->_instance->CreateFolderQuery();
          return scope.Close(WrapStorageFolderQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 1
        && args[0]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFolderQuery arg0 = static_cast<::Windows::Storage::Search::CommonFolderQuery>(args[0]->Int32Value());
          
          ::Windows::Storage::Search::StorageFolderQueryResult^ result;
          result = wrapper->_instance->CreateFolderQuery(arg0);
          return scope.Close(WrapStorageFolderQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> CreateFolderQueryWithOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          ::Windows::Storage::Search::StorageFolderQueryResult^ result;
          result = wrapper->_instance->CreateFolderQueryWithOptions(arg0);
          return scope.Close(WrapStorageFolderQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> CreateItemQuery(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::StorageItemQueryResult^ result;
          result = wrapper->_instance->CreateItemQuery();
          return scope.Close(WrapStorageItemQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> CreateItemQueryWithOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          ::Windows::Storage::Search::StorageItemQueryResult^ result;
          result = wrapper->_instance->CreateItemQueryWithOptions(arg0);
          return scope.Close(WrapStorageItemQueryResult(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> AreQueryOptionsSupported(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          bool result;
          result = wrapper->_instance->AreQueryOptionsSupported(arg0);
          return scope.Close(Boolean::New(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> IsCommonFolderQuerySupported(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 1
        && args[0]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFolderQuery arg0 = static_cast<::Windows::Storage::Search::CommonFolderQuery>(args[0]->Int32Value());
          
          bool result;
          result = wrapper->_instance->IsCommonFolderQuerySupported(arg0);
          return scope.Close(Boolean::New(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> IsCommonFileQuerySupported(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::IStorageFolderQueryOperations^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      IStorageFolderQueryOperations *wrapper = IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(args.This());

      if (args.Length() == 1
        && args[0]->IsInt32())
      {
        try
        {
          ::Windows::Storage::Search::CommonFileQuery arg0 = static_cast<::Windows::Storage::Search::CommonFileQuery>(args[0]->Int32Value());
          
          bool result;
          result = wrapper->_instance->IsCommonFileQuerySupported(arg0);
          return scope.Close(Boolean::New(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }





  private:
    ::Windows::Storage::Search::IStorageFolderQueryOperations^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapIStorageFolderQueryOperations(::Windows::Storage::Search::IStorageFolderQueryOperations^ wintRtInstance);
    friend ::Windows::Storage::Search::IStorageFolderQueryOperations^ UnwrapIStorageFolderQueryOperations(Handle<Value> value);
    friend bool IsIStorageFolderQueryOperationsWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> IStorageFolderQueryOperations::s_constructorTemplate;

  v8::Handle<v8::Value> WrapIStorageFolderQueryOperations(::Windows::Storage::Search::IStorageFolderQueryOperations^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(IStorageFolderQueryOperations::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::IStorageFolderQueryOperations^ UnwrapIStorageFolderQueryOperations(Handle<Value> value)
  {
     return IStorageFolderQueryOperations::Unwrap<IStorageFolderQueryOperations>(value.As<Object>())->_instance;
  }

  void InitIStorageFolderQueryOperations(Handle<Object> exports)
  {
    IStorageFolderQueryOperations::Init(exports);
  }

  class StorageFileQueryResult : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("StorageFileQueryResult"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
      Handle<Value> asyncSymbol = String::NewSymbol("__winRtAsync__");
      Handle<Function> func;
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getCurrentQueryOptions"), FunctionTemplate::New(GetCurrentQueryOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("applyNewQueryOptions"), FunctionTemplate::New(ApplyNewQueryOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getMatchingPropertiesWithRanges"), FunctionTemplate::New(GetMatchingPropertiesWithRanges)->GetFunction());
      
            
      func = FunctionTemplate::New(GetFilesAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getFilesAsync"), func);
      func = FunctionTemplate::New(GetItemCountAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getItemCountAsync"), func);
      func = FunctionTemplate::New(FindStartIndexAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("findStartIndexAsync"), func);
      
            
      Local<Function> addListenerFunc = FunctionTemplate::New(AddListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("addListener"), addListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("on"), addListenerFunc);
      Local<Function> removeListenerFunc = FunctionTemplate::New(RemoveListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("removeListener"), removeListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("off"), removeListenerFunc);
            
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("folder"), FolderGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("StorageFileQueryResult"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    StorageFileQueryResult(::Windows::Storage::Search::StorageFileQueryResult^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::StorageFileQueryResult^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::StorageFileQueryResult^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      StorageFileQueryResult *wrapperInstance = new StorageFileQueryResult(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


    static Handle<Value> GetFilesAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFile^>^>^ op;
    

      if (args.Length() == 3
        && args[0]->IsUint32()
        && args[1]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          
          op = wrapper->_instance->GetFilesAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetFilesAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFile^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Storage::StorageFile^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::StorageFile^ val) -> Handle<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFile", val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFile^>(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::StorageFile^ {
              return dynamic_cast<::Windows::Storage::StorageFile^>(NodeRT::Utils::GetObjectInstance(value));
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetItemCountAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetItemCountAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> FindStartIndexAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(args[0]))
      {
        try
        {
          ::Platform::Object^ arg0 = dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(args[0]));
          
          op = wrapper->_instance->FindStartIndexAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
  
    static Handle<Value> GetCurrentQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ result;
          result = wrapper->_instance->GetCurrentQueryOptions();
          return scope.Close(WrapQueryOptions(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> ApplyNewQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          wrapper->_instance->ApplyNewQueryOptions(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> GetMatchingPropertiesWithRanges(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFile^>(args[0]))
      {
        try
        {
          ::Windows::Storage::StorageFile^ arg0 = dynamic_cast<::Windows::Storage::StorageFile^>(NodeRT::Utils::GetObjectInstance(args[0]));
          
          ::Windows::Foundation::Collections::IMap<::Platform::String^, ::Windows::Foundation::Collections::IVectorView<::Windows::Data::Text::TextSegment>^>^ result;
          result = wrapper->_instance->GetMatchingPropertiesWithRanges(arg0);
          return scope.Close(NodeRT::Collections::MapWrapper<::Platform::String^,::Windows::Foundation::Collections::IVectorView<::Windows::Data::Text::TextSegment>^>::CreateMapWrapper(result, 
            [](::Platform::String^ val) -> Handle<Value> {
              return NodeRT::Utils::NewString(val->Data());
            },
            [](Handle<Value> value) -> bool {
              return value->IsString();
            },
            [](Handle<Value> value) -> ::Platform::String^ {
              return ref new Platform::String(NodeRT::Utils::StringToWchar(v8::String::Value(value)));
            },
            [](::Windows::Foundation::Collections::IVectorView<::Windows::Data::Text::TextSegment>^ val) -> Handle<Value> {
              return NodeRT::Collections::VectorViewWrapper<::Windows::Data::Text::TextSegment>::CreateVectorViewWrapper(val, 
            [](::Windows::Data::Text::TextSegment val) -> Handle<Value> {
              return TextSegmentToJsObject(val);
            },
            [](Handle<Value> value) -> bool {
              return IsTextSegmentJsObject(value);
            },
            [](Handle<Value> value) -> ::Windows::Data::Text::TextSegment {
              return TextSegmentFromJsObject(value);
            }
          );
            },
            [](Handle<Value> value) -> bool {
              return (NodeRT::Utils::IsWinRtWrapperOf<::Windows::Foundation::Collections::IVectorView<::Windows::Data::Text::TextSegment>^>(value) || value->IsArray());
            },
            [](Handle<Value> value) -> ::Windows::Foundation::Collections::IVectorView<::Windows::Data::Text::TextSegment>^ {
              return 
            [] (v8::Handle<v8::Value> value) -> ::Windows::Foundation::Collections::IVectorView<::Windows::Data::Text::TextSegment>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtVectorView<::Windows::Data::Text::TextSegment>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return IsTextSegmentJsObject(value);
                 },
                 [](Handle<Value> value) -> ::Windows::Data::Text::TextSegment {
                   return TextSegmentFromJsObject(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Windows::Foundation::Collections::IVectorView<::Windows::Data::Text::TextSegment>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (value);
            }
          ));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }



    static Handle<Value> FolderGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(info.This());

      try 
      {
        ::Windows::Storage::StorageFolder^ result = wrapper->_instance->Folder;
        return scope.Close(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


    static v8::Handle<v8::Value> AddListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected arguments are eventName(string),callback(function)")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;
      
      Local<Function> callback = args[1].As<Function>();
      
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->ContentsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->OptionsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else 
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
          tokenMap = Object::New();
          callback->SetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME), tokenMap);
      }

      tokenMap.As<Object>()->Set(args[1], CreateOpaqueWrapper(::Windows::Foundation::PropertyValue::CreateInt64(registrationToken.Value)));
                
      return scope.Close(Undefined());
    }

    static v8::Handle<v8::Value> RemoveListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected a string and a callback")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;

      if ((NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str)))
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Function> callback = args[1].As<Function>();
      Handle<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      Handle<Value> opaqueWrapperObj =  tokenMap.As<Object>()->Get(args[1]);

      if (opaqueWrapperObj.IsEmpty() || opaqueWrapperObj->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      OpaqueWrapper *opaqueWrapper = OpaqueWrapper::Unwrap<OpaqueWrapper>(opaqueWrapperObj.As<Object>());
            
      long long tokenValue = (long long) opaqueWrapper->GetObjectInstance();
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      registrationToken.Value = tokenValue;
        
      try 
      {
        if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());
          wrapper->_instance->ContentsChanged::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFileQueryResult^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          StorageFileQueryResult *wrapper = StorageFileQueryResult::Unwrap<StorageFileQueryResult>(args.This());
          wrapper->_instance->OptionsChanged::remove(registrationToken);
        }
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }

      tokenMap.As<Object>()->Delete(args[0].As<String>());

      return scope.Close(Undefined());
    }
  private:
    ::Windows::Storage::Search::StorageFileQueryResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapStorageFileQueryResult(::Windows::Storage::Search::StorageFileQueryResult^ wintRtInstance);
    friend ::Windows::Storage::Search::StorageFileQueryResult^ UnwrapStorageFileQueryResult(Handle<Value> value);
    friend bool IsStorageFileQueryResultWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> StorageFileQueryResult::s_constructorTemplate;

  v8::Handle<v8::Value> WrapStorageFileQueryResult(::Windows::Storage::Search::StorageFileQueryResult^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(StorageFileQueryResult::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::StorageFileQueryResult^ UnwrapStorageFileQueryResult(Handle<Value> value)
  {
     return StorageFileQueryResult::Unwrap<StorageFileQueryResult>(value.As<Object>())->_instance;
  }

  void InitStorageFileQueryResult(Handle<Object> exports)
  {
    StorageFileQueryResult::Init(exports);
  }

  class StorageFolderQueryResult : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("StorageFolderQueryResult"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
      Handle<Value> asyncSymbol = String::NewSymbol("__winRtAsync__");
      Handle<Function> func;
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getCurrentQueryOptions"), FunctionTemplate::New(GetCurrentQueryOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("applyNewQueryOptions"), FunctionTemplate::New(ApplyNewQueryOptions)->GetFunction());
      
            
      func = FunctionTemplate::New(GetFoldersAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getFoldersAsync"), func);
      func = FunctionTemplate::New(GetItemCountAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getItemCountAsync"), func);
      func = FunctionTemplate::New(FindStartIndexAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("findStartIndexAsync"), func);
      
            
      Local<Function> addListenerFunc = FunctionTemplate::New(AddListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("addListener"), addListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("on"), addListenerFunc);
      Local<Function> removeListenerFunc = FunctionTemplate::New(RemoveListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("removeListener"), removeListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("off"), removeListenerFunc);
            
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("folder"), FolderGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("StorageFolderQueryResult"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    StorageFolderQueryResult(::Windows::Storage::Search::StorageFolderQueryResult^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::StorageFolderQueryResult^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::StorageFolderQueryResult^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      StorageFolderQueryResult *wrapperInstance = new StorageFolderQueryResult(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


    static Handle<Value> GetFoldersAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFolder^>^>^ op;
    

      if (args.Length() == 3
        && args[0]->IsUint32()
        && args[1]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          
          op = wrapper->_instance->GetFoldersAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetFoldersAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::StorageFolder^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Storage::StorageFolder^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::StorageFolder^ val) -> Handle<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::StorageFolder^>(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::StorageFolder^ {
              return dynamic_cast<::Windows::Storage::StorageFolder^>(NodeRT::Utils::GetObjectInstance(value));
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetItemCountAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetItemCountAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> FindStartIndexAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(args[0]))
      {
        try
        {
          ::Platform::Object^ arg0 = dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(args[0]));
          
          op = wrapper->_instance->FindStartIndexAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
  
    static Handle<Value> GetCurrentQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ result;
          result = wrapper->_instance->GetCurrentQueryOptions();
          return scope.Close(WrapQueryOptions(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> ApplyNewQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          wrapper->_instance->ApplyNewQueryOptions(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }



    static Handle<Value> FolderGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(info.This());

      try 
      {
        ::Windows::Storage::StorageFolder^ result = wrapper->_instance->Folder;
        return scope.Close(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


    static v8::Handle<v8::Value> AddListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected arguments are eventName(string),callback(function)")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;
      
      Local<Function> callback = args[1].As<Function>();
      
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->ContentsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->OptionsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else 
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
          tokenMap = Object::New();
          callback->SetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME), tokenMap);
      }

      tokenMap.As<Object>()->Set(args[1], CreateOpaqueWrapper(::Windows::Foundation::PropertyValue::CreateInt64(registrationToken.Value)));
                
      return scope.Close(Undefined());
    }

    static v8::Handle<v8::Value> RemoveListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected a string and a callback")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;

      if ((NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str)))
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Function> callback = args[1].As<Function>();
      Handle<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      Handle<Value> opaqueWrapperObj =  tokenMap.As<Object>()->Get(args[1]);

      if (opaqueWrapperObj.IsEmpty() || opaqueWrapperObj->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      OpaqueWrapper *opaqueWrapper = OpaqueWrapper::Unwrap<OpaqueWrapper>(opaqueWrapperObj.As<Object>());
            
      long long tokenValue = (long long) opaqueWrapper->GetObjectInstance();
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      registrationToken.Value = tokenValue;
        
      try 
      {
        if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());
          wrapper->_instance->ContentsChanged::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageFolderQueryResult^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          StorageFolderQueryResult *wrapper = StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(args.This());
          wrapper->_instance->OptionsChanged::remove(registrationToken);
        }
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }

      tokenMap.As<Object>()->Delete(args[0].As<String>());

      return scope.Close(Undefined());
    }
  private:
    ::Windows::Storage::Search::StorageFolderQueryResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapStorageFolderQueryResult(::Windows::Storage::Search::StorageFolderQueryResult^ wintRtInstance);
    friend ::Windows::Storage::Search::StorageFolderQueryResult^ UnwrapStorageFolderQueryResult(Handle<Value> value);
    friend bool IsStorageFolderQueryResultWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> StorageFolderQueryResult::s_constructorTemplate;

  v8::Handle<v8::Value> WrapStorageFolderQueryResult(::Windows::Storage::Search::StorageFolderQueryResult^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(StorageFolderQueryResult::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::StorageFolderQueryResult^ UnwrapStorageFolderQueryResult(Handle<Value> value)
  {
     return StorageFolderQueryResult::Unwrap<StorageFolderQueryResult>(value.As<Object>())->_instance;
  }

  void InitStorageFolderQueryResult(Handle<Object> exports)
  {
    StorageFolderQueryResult::Init(exports);
  }

  class StorageItemQueryResult : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("StorageItemQueryResult"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
      Handle<Value> asyncSymbol = String::NewSymbol("__winRtAsync__");
      Handle<Function> func;
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getCurrentQueryOptions"), FunctionTemplate::New(GetCurrentQueryOptions)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("applyNewQueryOptions"), FunctionTemplate::New(ApplyNewQueryOptions)->GetFunction());
      
            
      func = FunctionTemplate::New(GetItemsAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getItemsAsync"), func);
      func = FunctionTemplate::New(GetItemCountAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getItemCountAsync"), func);
      func = FunctionTemplate::New(FindStartIndexAsync)->GetFunction();
      func->Set(asyncSymbol, True(), PropertyAttribute::DontEnum);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("findStartIndexAsync"), func);
      
            
      Local<Function> addListenerFunc = FunctionTemplate::New(AddListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("addListener"), addListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("on"), addListenerFunc);
      Local<Function> removeListenerFunc = FunctionTemplate::New(RemoveListener)->GetFunction();
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("removeListener"), removeListenerFunc);
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("off"), removeListenerFunc);
            
      s_constructorTemplate->PrototypeTemplate()->SetAccessor(String::NewSymbol("folder"), FolderGetter);
      
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("StorageItemQueryResult"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    StorageItemQueryResult(::Windows::Storage::Search::StorageItemQueryResult^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::StorageItemQueryResult^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::StorageItemQueryResult^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      StorageItemQueryResult *wrapperInstance = new StorageItemQueryResult(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


    static Handle<Value> GetItemsAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::IStorageItem^>^>^ op;
    

      if (args.Length() == 3
        && args[0]->IsUint32()
        && args[1]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          unsigned int arg1 = static_cast<unsigned int>(args[1]->IntegerValue());
          
          op = wrapper->_instance->GetItemsAsync(arg0,arg1);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetItemsAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<::Windows::Foundation::Collections::IVectorView<::Windows::Storage::IStorageItem^>^> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = NodeRT::Collections::VectorViewWrapper<::Windows::Storage::IStorageItem^>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::IStorageItem^ val) -> Handle<Value> {
              return NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "IStorageItem", val);
            },
            [](Handle<Value> value) -> bool {
              return NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::IStorageItem^>(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::IStorageItem^ {
              return dynamic_cast<::Windows::Storage::IStorageItem^>(NodeRT::Utils::GetObjectInstance(value));
            }
          );
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> GetItemCountAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 1)
      {
        try
        {
          op = wrapper->_instance->GetItemCountAsync();
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
    static Handle<Value> FindStartIndexAsync(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      if (args.Length() == 0 || !args[args.Length() -1]->IsFunction())
      {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: No callback was given")));
          return scope.Close(Undefined());
      }

      StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());

      ::Windows::Foundation::IAsyncOperation<unsigned int>^ op;
    

      if (args.Length() == 2
        && NodeRT::Utils::IsWinRtWrapperOf<::Platform::Object^>(args[0]))
      {
        try
        {
          ::Platform::Object^ arg0 = dynamic_cast<::Platform::Object^>(NodeRT::Utils::GetObjectInstance(args[0]));
          
          op = wrapper->_instance->FindStartIndexAsync(arg0);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }
    
      auto opTask = create_task(op);
      uv_async_t* asyncToken = NodeUtils::Async::GetAsyncToken(args[args.Length() -1].As<Function>());

      opTask.then( [asyncToken] (task<unsigned int> t) 
      {	
        try
        {
          auto result = t.get();
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [result](NodeUtils::InvokeCallbackDelegate invokeCallback) {


            TryCatch tryCatch;
            Handle<Value> error; 
            Handle<Value> arg1 = Integer::New(result);
            if (tryCatch.HasCaught())
            {
              error = tryCatch.Exception()->ToObject();
            }
            else 
            {
              error = Undefined();
            }
            if (arg1.IsEmpty()) arg1 = Undefined();
            Handle<Value> args[] = {error, arg1};

            invokeCallback(_countof(args), args);
          });
        }
        catch (Platform::Exception^ exception)
        {
          NodeUtils::Async::RunCallbackOnMain(asyncToken, [exception](NodeUtils::InvokeCallbackDelegate invokeCallback) {
             
            Handle<Value> error = NodeRT::Utils::WinRtExceptionToJsError(exception);
        
            Handle<Value> args[] = {error};
            invokeCallback(_countof(args), args);
          });
        }  		
      });

      return scope.Close(Undefined());
    }
  
    static Handle<Value> GetCurrentQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ result;
          result = wrapper->_instance->GetCurrentQueryOptions();
          return scope.Close(WrapQueryOptions(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> ApplyNewQueryOptions(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());

      if (args.Length() == 1
        && NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::QueryOptions^>(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::QueryOptions^ arg0 = UnwrapQueryOptions(args[0]);
          
          wrapper->_instance->ApplyNewQueryOptions(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }



    static Handle<Value> FolderGetter(Local<String> property, const AccessorInfo &info)
    {
      HandleScope scope;
      
      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(info.This()))
      {
        return scope.Close(Undefined());
      }

      StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(info.This());

      try 
      {
        ::Windows::Storage::StorageFolder^ result = wrapper->_instance->Folder;
        return scope.Close(NodeRT::Utils::CreateExternalWinRTObject("Windows.Storage", "StorageFolder", result));
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
        return scope.Close(Undefined());
      }
    }
    


    static v8::Handle<v8::Value> AddListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected arguments are eventName(string),callback(function)")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;
      
      Local<Function> callback = args[1].As<Function>();
      
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->ContentsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
      {
        if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
        {
          ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
          return scope.Close(Undefined());
        }
        StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());
      
        try
        {
          std::shared_ptr<Persistent<Object>> callbackObjPtr(new Persistent<Object>(Persistent<Object>::New(NodeRT::Utils::CreateCallbackObjectInDomain(callback))), 
            [] (Persistent<Object> *ptr ) {
              NodeUtils::Async::RunOnMain([ptr]() {
                ptr->Dispose();
                delete ptr;
            });
          });

          registrationToken = wrapper->_instance->OptionsChanged::add(
            ref new ::Windows::Foundation::TypedEventHandler<::Windows::Storage::Search::IStorageQueryResultBase^, ::Platform::Object^>(
            [callbackObjPtr](::Windows::Storage::Search::IStorageQueryResultBase^ arg0, ::Platform::Object^ arg1) {
              NodeUtils::Async::RunOnMain([callbackObjPtr , arg0, arg1]() {
                TryCatch tryCatch;
              
                Handle<Value> error;

                Handle<Value> wrappedArg0 = WrapIStorageQueryResultBase(arg0);
                Handle<Value> wrappedArg1 = CreateOpaqueWrapper(arg1);

                if (tryCatch.HasCaught())
                {
                  error = tryCatch.Exception()->ToObject();
                }
                else 
                {
                  error = Undefined();
                }


                if (wrappedArg0.IsEmpty()) wrappedArg0 = Undefined();
                if (wrappedArg1.IsEmpty()) wrappedArg1 = Undefined();

                Handle<Value> args[] = { wrappedArg0, wrappedArg1 };
                NodeRT::Utils::CallCallbackInDomain(*callbackObjPtr, _countof(args), args);
              });
            })
          );
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }

      }
      else 
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
          tokenMap = Object::New();
          callback->SetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME), tokenMap);
      }

      tokenMap.As<Object>()->Set(args[1], CreateOpaqueWrapper(::Windows::Foundation::PropertyValue::CreateInt64(registrationToken.Value)));
                
      return scope.Close(Undefined());
    }

    static v8::Handle<v8::Value> RemoveListener(const v8::Arguments& args)
    {
      HandleScope scope;

      if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsFunction())
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"wrong arguments, expected a string and a callback")));
        return scope.Close(Undefined());
      }

      String::Value eventName(args[0]);
      auto str = *eventName;

      if ((NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str)) &&(NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str)))
      {
        ThrowException(Exception::Error(String::Concat(NodeRT::Utils::NewString(L"given event name isn't supported: "), args[0].As<String>())));
        return scope.Close(Undefined());
      }

      Local<Function> callback = args[1].As<Function>();
      Handle<Value> tokenMap = callback->GetHiddenValue(String::NewSymbol(REGISTRATION_TOKEN_MAP_PROPERTY_NAME));
                
      if (tokenMap.IsEmpty() || tokenMap->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      Handle<Value> opaqueWrapperObj =  tokenMap.As<Object>()->Get(args[1]);

      if (opaqueWrapperObj.IsEmpty() || opaqueWrapperObj->Equals(Undefined()))
      {
        return scope.Close(Undefined());
      }

      OpaqueWrapper *opaqueWrapper = OpaqueWrapper::Unwrap<OpaqueWrapper>(opaqueWrapperObj.As<Object>());
            
      long long tokenValue = (long long) opaqueWrapper->GetObjectInstance();
      ::Windows::Foundation::EventRegistrationToken registrationToken;
      registrationToken.Value = tokenValue;
        
      try 
      {
        if (NodeRT::Utils::CaseInsenstiveEquals(L"contentsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());
          wrapper->_instance->ContentsChanged::remove(registrationToken);
        }
        else if (NodeRT::Utils::CaseInsenstiveEquals(L"optionsChanged", str))
        {
          if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::StorageItemQueryResult^>(args.This()))
          {
            ThrowException(Exception::Error(NodeRT::Utils::NewString(L"The caller of this method isn't of the expected type or internal WinRt object was disposed")));
            return scope.Close(Undefined());
          }
          StorageItemQueryResult *wrapper = StorageItemQueryResult::Unwrap<StorageItemQueryResult>(args.This());
          wrapper->_instance->OptionsChanged::remove(registrationToken);
        }
      }
      catch (Platform::Exception ^exception)
      {
        NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
      }

      tokenMap.As<Object>()->Delete(args[0].As<String>());

      return scope.Close(Undefined());
    }
  private:
    ::Windows::Storage::Search::StorageItemQueryResult^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapStorageItemQueryResult(::Windows::Storage::Search::StorageItemQueryResult^ wintRtInstance);
    friend ::Windows::Storage::Search::StorageItemQueryResult^ UnwrapStorageItemQueryResult(Handle<Value> value);
    friend bool IsStorageItemQueryResultWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> StorageItemQueryResult::s_constructorTemplate;

  v8::Handle<v8::Value> WrapStorageItemQueryResult(::Windows::Storage::Search::StorageItemQueryResult^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(StorageItemQueryResult::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::StorageItemQueryResult^ UnwrapStorageItemQueryResult(Handle<Value> value)
  {
     return StorageItemQueryResult::Unwrap<StorageItemQueryResult>(value.As<Object>())->_instance;
  }

  void InitStorageItemQueryResult(Handle<Object> exports)
  {
    StorageItemQueryResult::Init(exports);
  }

  class SortEntryVector : public WrapperBase
  {
  public:    
    static v8::Handle<v8::Value> Init(const Handle<Object> exports)
    {
      HandleScope scope;
      
      s_constructorTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(New));
      s_constructorTemplate->SetClassName(String::NewSymbol("SortEntryVector"));
      s_constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);
      
            
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getAt"), FunctionTemplate::New(GetAt)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getView"), FunctionTemplate::New(GetView)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("indexOf"), FunctionTemplate::New(IndexOf)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("setAt"), FunctionTemplate::New(SetAt)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("insertAt"), FunctionTemplate::New(InsertAt)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("removeAt"), FunctionTemplate::New(RemoveAt)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("append"), FunctionTemplate::New(Append)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("removeAtEnd"), FunctionTemplate::New(RemoveAtEnd)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("clear"), FunctionTemplate::New(Clear)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("getMany"), FunctionTemplate::New(GetMany)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("replaceAll"), FunctionTemplate::New(ReplaceAll)->GetFunction());
      s_constructorTemplate->PrototypeTemplate()->Set(String::NewSymbol("first"), FunctionTemplate::New(First)->GetFunction());
      
                        
      Local<Function> constructor = s_constructorTemplate->GetFunction();


      exports->Set(String::NewSymbol("SortEntryVector"), constructor);
      return scope.Close(Undefined());
    }


    virtual ::Platform::Object^ GetObjectInstance() const override
    {
      return _instance;
    }

  private:
    
    SortEntryVector(::Windows::Storage::Search::SortEntryVector^ instance)
    {
      _instance = instance;
    }
    
    
    static v8::Handle<v8::Value> New(const v8::Arguments& args)
    {
      HandleScope scope;

      // in case the constructor was called without the new operator
      if (!s_constructorTemplate->HasInstance(args.This()))
      {
        if (args.Length() > 0)
        {
          std::unique_ptr<Handle<Value> []> constructorArgs(new Handle<Value>[args.Length()]);

          Handle<Value> *argsPtr = constructorArgs.get();
          for (int i = 0; i < args.Length(); i++)
          {
            argsPtr[i] = args[i];
          }

          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), constructorArgs.get());
        }
        else
        {
          return s_constructorTemplate->GetFunction()->CallAsConstructor(args.Length(), nullptr);
        }
      }
      
      ::Windows::Storage::Search::SortEntryVector^ winRtInstance;


      if (args.Length() == 1 && OpaqueWrapper::IsOpaqueWrapper(args[0]) &&
        NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args[0]))
      {
        try 
        {
          winRtInstance = (::Windows::Storage::Search::SortEntryVector^) NodeRT::Utils::GetObjectInstance(args[0]);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Invalid arguments, no suitable constructor found")));
        return scope.Close(Undefined());
      }

      args.This()->SetHiddenValue(String::NewSymbol("__winRtInstance__"), True());

      SortEntryVector *wrapperInstance = new SortEntryVector(winRtInstance);
      wrapperInstance->Wrap(args.This());

      return args.This();
    }


  
    static Handle<Value> GetAt(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 1
        && args[0]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          
          ::Windows::Storage::Search::SortEntry result;
          result = wrapper->_instance->GetAt(arg0);
          return scope.Close(SortEntryToJsObject(result));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> GetView(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Foundation::Collections::IVectorView<::Windows::Storage::Search::SortEntry>^ result;
          result = wrapper->_instance->GetView();
          return scope.Close(NodeRT::Collections::VectorViewWrapper<::Windows::Storage::Search::SortEntry>::CreateVectorViewWrapper(result, 
            [](::Windows::Storage::Search::SortEntry val) -> Handle<Value> {
              return SortEntryToJsObject(val);
            },
            [](Handle<Value> value) -> bool {
              return IsSortEntryJsObject(value);
            },
            [](Handle<Value> value) -> ::Windows::Storage::Search::SortEntry {
              return SortEntryFromJsObject(value);
            }
          ));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> IndexOf(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 1
        && IsSortEntryJsObject(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::SortEntry arg0 = SortEntryFromJsObject(args[0]);
          unsigned int arg1;
          
          bool result;
          result = wrapper->_instance->IndexOf(arg0, &arg1);
          Handle<Object> resObj = Object::New();
          resObj->Set(String::NewSymbol("boolean"), Boolean::New(result));
          resObj->Set(String::NewSymbol("index"), Integer::New(arg1));
          return scope.Close(resObj);
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> SetAt(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 2
        && args[0]->IsUint32()
        && IsSortEntryJsObject(args[1]))
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          ::Windows::Storage::Search::SortEntry arg1 = SortEntryFromJsObject(args[1]);
          
          wrapper->_instance->SetAt(arg0, arg1);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> InsertAt(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 2
        && args[0]->IsUint32()
        && IsSortEntryJsObject(args[1]))
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          ::Windows::Storage::Search::SortEntry arg1 = SortEntryFromJsObject(args[1]);
          
          wrapper->_instance->InsertAt(arg0, arg1);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> RemoveAt(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 1
        && args[0]->IsUint32())
      {
        try
        {
          unsigned int arg0 = static_cast<unsigned int>(args[0]->IntegerValue());
          
          wrapper->_instance->RemoveAt(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> Append(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 1
        && IsSortEntryJsObject(args[0]))
      {
        try
        {
          ::Windows::Storage::Search::SortEntry arg0 = SortEntryFromJsObject(args[0]);
          
          wrapper->_instance->Append(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> RemoveAtEnd(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          wrapper->_instance->RemoveAtEnd();
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> Clear(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          wrapper->_instance->Clear();
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> GetMany(const v8::Arguments& args)
    {
      HandleScope scope;
      ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Not implemented")));
      return scope.Close(Undefined());
    }
    static Handle<Value> ReplaceAll(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 1
        && (NodeRT::Utils::IsWinRtWrapperOf<::Platform::Array<::Windows::Storage::Search::SortEntry>^>(args[0]) || args[0]->IsArray()))
      {
        try
        {
          ::Platform::Array<::Windows::Storage::Search::SortEntry>^ arg0 = 
            [] (v8::Handle<v8::Value> value) -> ::Platform::Array<::Windows::Storage::Search::SortEntry>^
            {
              if (value->IsArray())
              {
                return NodeRT::Collections::JsArrayToWinrtArray<::Windows::Storage::Search::SortEntry>(value.As<Array>(), 
                 [](Handle<Value> value) -> bool {
                   return IsSortEntryJsObject(value);
                 },
                 [](Handle<Value> value) -> ::Windows::Storage::Search::SortEntry {
                   return SortEntryFromJsObject(value);
                 }
                );
              }
              else
              {
                return dynamic_cast<::Platform::Array<::Windows::Storage::Search::SortEntry>^>(NodeRT::Utils::GetObjectInstance(value));
              }
            } (args[0]);
          
          wrapper->_instance->ReplaceAll(arg0);
          return scope.Close(Undefined());   
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }
    static Handle<Value> First(const v8::Arguments& args)
    {
      HandleScope scope;

      if (!NodeRT::Utils::IsWinRtWrapperOf<::Windows::Storage::Search::SortEntryVector^>(args.This()))
      {
        return scope.Close(Undefined());
      }

      SortEntryVector *wrapper = SortEntryVector::Unwrap<SortEntryVector>(args.This());

      if (args.Length() == 0)
      {
        try
        {
          ::Windows::Foundation::Collections::IIterator<::Windows::Storage::Search::SortEntry>^ result;
          result = wrapper->_instance->First();
          return scope.Close(NodeRT::Collections::IteratorWrapper<::Windows::Storage::Search::SortEntry>::CreateIteratorWrapper(result, 
            [](::Windows::Storage::Search::SortEntry val) -> Handle<Value> {
              return SortEntryToJsObject(val);
            }
          ));
        }
        catch (Platform::Exception ^exception)
        {
          NodeRT::Utils::ThrowWinRtExceptionInJs(exception);
          return scope.Close(Undefined());
        }
      }
      else 
      {
        ThrowException(Exception::Error(NodeRT::Utils::NewString(L"Bad arguments: no suitable overload found")));
        return scope.Close(Undefined());
      }

      return scope.Close(Undefined());
    }





  private:
    ::Windows::Storage::Search::SortEntryVector^ _instance;
    static Persistent<FunctionTemplate> s_constructorTemplate;

    friend v8::Handle<v8::Value> WrapSortEntryVector(::Windows::Storage::Search::SortEntryVector^ wintRtInstance);
    friend ::Windows::Storage::Search::SortEntryVector^ UnwrapSortEntryVector(Handle<Value> value);
    friend bool IsSortEntryVectorWrapper(Handle<Value> value);
  };
  Persistent<FunctionTemplate> SortEntryVector::s_constructorTemplate;

  v8::Handle<v8::Value> WrapSortEntryVector(::Windows::Storage::Search::SortEntryVector^ winRtInstance)
  {
    HandleScope scope;

    if (winRtInstance == nullptr)
    {
      return scope.Close(Undefined());
    }

    Handle<Object> opaqueWrapper = CreateOpaqueWrapper(winRtInstance);
    Handle<Value> args[] = {opaqueWrapper};
    return scope.Close(SortEntryVector::s_constructorTemplate->GetFunction()->NewInstance(_countof(args), args));
  }

  ::Windows::Storage::Search::SortEntryVector^ UnwrapSortEntryVector(Handle<Value> value)
  {
     return SortEntryVector::Unwrap<SortEntryVector>(value.As<Object>())->_instance;
  }

  void InitSortEntryVector(Handle<Object> exports)
  {
    SortEntryVector::Init(exports);
  }

} } } } 

void init(Handle<Object> exports)
{
  if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
  {
    ThrowException(v8::Exception::Error(NodeRT::Utils::NewString(L"error in CoInitializeEx()")));
    return;
  }
  
  NodeRT::Windows::Storage::Search::InitDateStackOptionEnum(exports);
  NodeRT::Windows::Storage::Search::InitIndexerOptionEnum(exports);
  NodeRT::Windows::Storage::Search::InitFolderDepthEnum(exports);
  NodeRT::Windows::Storage::Search::InitCommonFileQueryEnum(exports);
  NodeRT::Windows::Storage::Search::InitCommonFolderQueryEnum(exports);
  NodeRT::Windows::Storage::Search::InitIndexedStateEnum(exports);
  NodeRT::Windows::Storage::Search::InitContentIndexer(exports);
  NodeRT::Windows::Storage::Search::InitIIndexableContent(exports);
  NodeRT::Windows::Storage::Search::InitValueAndLanguage(exports);
  NodeRT::Windows::Storage::Search::InitContentIndexerQuery(exports);
  NodeRT::Windows::Storage::Search::InitIndexableContent(exports);
  NodeRT::Windows::Storage::Search::InitQueryOptions(exports);
  NodeRT::Windows::Storage::Search::InitIStorageQueryResultBase(exports);
  NodeRT::Windows::Storage::Search::InitIStorageFolderQueryOperations(exports);
  NodeRT::Windows::Storage::Search::InitStorageFileQueryResult(exports);
  NodeRT::Windows::Storage::Search::InitStorageFolderQueryResult(exports);
  NodeRT::Windows::Storage::Search::InitStorageItemQueryResult(exports);
  NodeRT::Windows::Storage::Search::InitSortEntryVector(exports);

  NodeRT::Utils::RegisterNameSpace("Windows.Storage.Search", exports);
}


NODE_MODULE(binding, init)