Add support for WinRT in the MF capture framework by removing the disallowed calls...
authorGregoryMorse <gregory.morse@live.com>
Sat, 14 Dec 2013 08:53:30 +0000 (16:53 +0800)
committerGregoryMorse <gregory.morse@live.com>
Wed, 10 Sep 2014 09:05:52 +0000 (17:05 +0800)
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.

My discussion and proposal to finish this change:
 Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.

ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.

The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.

It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.

Fixed bugs and completed the change.  I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction).  Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it).  Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled).  After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft.  This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration.  Better to document that it is not supported.

Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.

The remaining changes are not difficult and will be complete soon along with debug tracing messages.

Update and rename cap_msmf.h to cap_msmf.hpp

Successful test - samples are grabbed

Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Fixed trailing whitespace

VS 2013 support and cleanup consistency plus C++/CX new object fixed

Conflicts:
modules/highgui/src/cap_msmf.cpp
modules/highgui/src/cap_msmf.hpp
modules/highgui/src/ppltasks_winrt.h

Fix merge conflicts

VS 2013 Update 2 library bug fix integrated

a-wi's changed integrated

modules/highgui/src/agile_wrl.h [new file with mode: 0644]
modules/highgui/src/cap_msmf.cpp
modules/highgui/src/cap_msmf.hpp
modules/highgui/src/ppltasks_winrt.h

diff --git a/modules/highgui/src/agile_wrl.h b/modules/highgui/src/agile_wrl.h
new file mode 100644 (file)
index 0000000..99fbf41
--- /dev/null
@@ -0,0 +1,568 @@
+//
+// Copyright (C) Microsoft Corporation
+// All rights reserved.
+// Modified for native C++ WRL support by Gregory Morse
+//
+// Code in Details namespace is for internal usage within the library code
+//
+
+#ifndef _PLATFORM_AGILE_H_
+#define _PLATFORM_AGILE_H_
+
+#ifdef _MSC_VER
+#pragma once
+#endif  // _MSC_VER
+
+#include <algorithm>
+#include <wrl\client.h>
+
+template <typename T, bool TIsNotAgile> class Agile;
+
+template <typename T>
+struct UnwrapAgile
+{
+    static const bool _IsAgile = false;
+};
+template <typename T>
+struct UnwrapAgile<Agile<T, false>>
+{
+    static const bool _IsAgile = true;
+};
+template <typename T>
+struct UnwrapAgile<Agile<T, true>>
+{
+    static const bool _IsAgile = true;
+};
+
+#define IS_AGILE(T) UnwrapAgile<T>::_IsAgile
+
+#define __is_winrt_agile(T) (std::is_same<T, HSTRING__>::value || std::is_base_of<Microsoft::WRL::FtmBase, T>::value || std::is_base_of<IAgileObject, T>::value) //derived from Microsoft::WRL::FtmBase or IAgileObject
+
+#define __is_win_interface(T) (std::is_base_of<IUnknown, T>::value || std::is_base_of<IInspectable, T>::value) //derived from IUnknown or IInspectable
+
+#define __is_win_class(T) (std::is_same<T, HSTRING__>::value || std::is_base_of<Microsoft::WRL::Details::RuntimeClassBase, T>::value) //derived from Microsoft::WRL::RuntimeClass or HSTRING
+
+    namespace Details
+    {
+        IUnknown* __stdcall GetObjectContext();
+        HRESULT __stdcall GetProxyImpl(IUnknown*, REFIID, IUnknown*, IUnknown**);
+        HRESULT __stdcall ReleaseInContextImpl(IUnknown*, IUnknown*);
+
+        template <typename T>
+#if _MSC_VER >= 1800
+        __declspec(no_refcount) inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy)
+#else
+        inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy)
+#endif
+        {
+#if _MSC_VER >= 1800
+            return GetProxyImpl(*reinterpret_cast<IUnknown**>(&ObjectIn), __uuidof(T*), ContextCallBack, reinterpret_cast<IUnknown**>(Proxy));
+#else
+            return GetProxyImpl(*reinterpret_cast<IUnknown**>(&const_cast<T*>(ObjectIn)), __uuidof(T*), ContextCallBack, reinterpret_cast<IUnknown**>(Proxy));
+#endif
+        }
+
+        template <typename T>
+        inline HRESULT ReleaseInContext(T *ObjectIn, IUnknown *ContextCallBack)
+        {
+            return ReleaseInContextImpl(ObjectIn, ContextCallBack);
+        }
+
+        template <typename T>
+        class AgileHelper
+        {
+            __abi_IUnknown* _p;
+            bool _release;
+        public:
+            AgileHelper(__abi_IUnknown* p, bool release = true) : _p(p), _release(release)
+            {
+            }
+            AgileHelper(AgileHelper&& other) : _p(other._p), _release(other._release)
+            {
+                _other._p = nullptr;
+                _other._release = true;
+            }
+            AgileHelper operator=(AgileHelper&& other)
+            {
+                _p = other._p;
+                _release = other._release;
+                _other._p = nullptr;
+                _other._release = true;
+                return *this;
+            }
+
+            ~AgileHelper()
+            {
+                if (_release && _p)
+                {
+                    _p->__abi_Release();
+                }
+            }
+
+            __declspec(no_refcount) __declspec(no_release_return)
+                T* operator->()
+            {
+                    return reinterpret_cast<T*>(_p);
+            }
+
+            __declspec(no_refcount) __declspec(no_release_return)
+                operator T * ()
+            {
+                    return reinterpret_cast<T*>(_p);
+            }
+        private:
+            AgileHelper(const AgileHelper&);
+            AgileHelper operator=(const AgileHelper&);
+        };
+        template <typename T>
+        struct __remove_hat
+        {
+            typedef T type;
+        };
+        template <typename T>
+        struct __remove_hat<T*>
+        {
+            typedef T type;
+        };
+        template <typename T>
+        struct AgileTypeHelper
+        {
+            typename typedef __remove_hat<T>::type type;
+            typename typedef __remove_hat<T>::type* agileMemberType;
+        };
+    } // namespace Details
+
+#pragma warning(push)
+#pragma warning(disable: 4451) // Usage of ref class inside this context can lead to invalid marshaling of object across contexts
+
+    template <
+        typename T,
+        bool TIsNotAgile = (__is_win_class(typename Details::AgileTypeHelper<T>::type) && !__is_winrt_agile(typename Details::AgileTypeHelper<T>::type)) ||
+        __is_win_interface(typename Details::AgileTypeHelper<T>::type)
+    >
+    class Agile
+    {
+        static_assert(__is_win_class(typename Details::AgileTypeHelper<T>::type) || __is_win_interface(typename Details::AgileTypeHelper<T>::type), "Agile can only be used with ref class or interface class types");
+        typename typedef Details::AgileTypeHelper<T>::agileMemberType TypeT;
+        TypeT _object;
+        ::Microsoft::WRL::ComPtr<IUnknown> _contextCallback;
+        ULONG_PTR _contextToken;
+
+#if _MSC_VER >= 1800
+        enum class AgileState
+        {
+            NonAgilePointer = 0,
+            AgilePointer = 1,
+            Unknown = 2
+        };
+        AgileState _agileState;
+#endif
+
+        void CaptureContext()
+        {
+            _contextCallback = Details::GetObjectContext();
+            __abi_ThrowIfFailed(CoGetContextToken(&_contextToken));
+        }
+
+        void SetObject(TypeT object)
+        {
+            // Capture context before setting the pointer
+            // If context capture fails then nothing to cleanup
+            Release();
+            if (object != nullptr)
+            {
+                ::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile;
+                HRESULT hr = reinterpret_cast<IUnknown*>(object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile);
+                // Don't Capture context if object is agile
+                if (hr != S_OK)
+                {
+#if _MSC_VER >= 1800
+                    _agileState = AgileState::NonAgilePointer;
+#endif
+                    CaptureContext();
+                }
+#if _MSC_VER >= 1800
+                else
+                {
+                    _agileState = AgileState::AgilePointer;
+                }
+#endif
+            }
+            _object = object;
+        }
+
+    public:
+        Agile() throw() : _object(nullptr), _contextToken(0)
+#if _MSC_VER >= 1800
+            , _agileState(AgileState::Unknown)
+#endif
+        {
+        }
+
+        Agile(nullptr_t) throw() : _object(nullptr), _contextToken(0)
+#if _MSC_VER >= 1800
+            , _agileState(AgileState::Unknown)
+#endif
+        {
+        }
+
+        explicit Agile(TypeT object) throw() : _object(nullptr), _contextToken(0)
+#if _MSC_VER >= 1800
+            , _agileState(AgileState::Unknown)
+#endif
+        {
+            // Assumes that the source object is from the current context
+            SetObject(object);
+        }
+
+        Agile(const Agile& object) throw() : _object(nullptr), _contextToken(0)
+#if _MSC_VER >= 1800
+            , _agileState(AgileState::Unknown)
+#endif
+        {
+            // Get returns pointer valid for current context
+            SetObject(object.Get());
+        }
+
+        Agile(Agile&& object) throw() : _object(nullptr), _contextToken(0)
+#if _MSC_VER >= 1800
+            , _agileState(AgileState::Unknown)
+#endif
+        {
+            // Assumes that the source object is from the current context
+            Swap(object);
+        }
+
+        ~Agile() throw()
+        {
+            Release();
+        }
+
+        TypeT Get() const
+        {
+            // Agile object, no proxy required
+#if _MSC_VER >= 1800
+            if (_agileState == AgileState::AgilePointer || _object == nullptr)
+#else
+            if (_contextToken == 0 || _contextCallback == nullptr || _object == nullptr)
+#endif
+            {
+                return _object;
+            }
+
+            // Do the check for same context
+            ULONG_PTR currentContextToken;
+            __abi_ThrowIfFailed(CoGetContextToken(&currentContextToken));
+            if (currentContextToken == _contextToken)
+            {
+                return _object;
+            }
+
+#if _MSC_VER >= 1800
+            // Different context and holding on to a non agile object
+            // Do the costly work of getting a proxy
+            TypeT localObject;
+            __abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject));
+
+            if (_agileState == AgileState::Unknown)
+#else
+            // Object is agile if it implements IAgileObject
+            // GetAddressOf captures the context with out knowing the type of object that it will hold
+            if (_object != nullptr)
+#endif
+            {
+#if _MSC_VER >= 1800
+                // Object is agile if it implements IAgileObject
+                // GetAddressOf captures the context with out knowing the type of object that it will hold
+                ::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile;
+                HRESULT hr = reinterpret_cast<IUnknown*>(localObject)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile);
+#else
+                ::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile;
+                HRESULT hr = reinterpret_cast<IUnknown*>(_object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile);
+#endif
+                if (hr == S_OK)
+                {
+                    auto pThis = const_cast<Agile*>(this);
+#if _MSC_VER >= 1800
+                    pThis->_agileState = AgileState::AgilePointer;
+#endif
+                    pThis->_contextToken = 0;
+                    pThis->_contextCallback = nullptr;
+                    return _object;
+                }
+#if _MSC_VER >= 1800
+                else
+                {
+                    auto pThis = const_cast<Agile*>(this);
+                    pThis->_agileState = AgileState::NonAgilePointer;
+                }
+#endif
+            }
+
+#if _MSC_VER < 1800
+            // Different context and holding on to a non agile object
+            // Do the costly work of getting a proxy
+            TypeT localObject;
+            __abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject));
+#endif
+            return localObject;
+        }
+
+        TypeT* GetAddressOf() throw()
+        {
+            Release();
+            CaptureContext();
+            return &_object;
+        }
+
+        TypeT* GetAddressOfForInOut() throw()
+        {
+            CaptureContext();
+            return &_object;
+        }
+
+        TypeT operator->() const throw()
+        {
+            return Get();
+        }
+
+        Agile& operator=(nullptr_t) throw()
+        {
+            Release();
+            return *this;
+        }
+
+        Agile& operator=(TypeT object) throw()
+        {
+            Agile(object).Swap(*this);
+            return *this;
+        }
+
+        Agile& operator=(Agile object) throw()
+        {
+            // parameter is by copy which gets pointer valid for current context
+            object.Swap(*this);
+            return *this;
+        }
+
+#if _MSC_VER < 1800
+        Agile& operator=(IUnknown* lp) throw()
+        {
+            // bump ref count
+            ::Microsoft::WRL::ComPtr<IUnknown> spObject(lp);
+
+            // put it into Platform Object
+            Platform::Object object;
+            *(IUnknown**)(&object) = spObject.Detach();
+
+            SetObject(object);
+            return *this;
+        }
+#endif
+
+        void Swap(Agile& object)
+        {
+            std::swap(_object, object._object);
+            std::swap(_contextCallback, object._contextCallback);
+            std::swap(_contextToken, object._contextToken);
+#if _MSC_VER >= 1800
+            std::swap(_agileState, object._agileState);
+#endif
+        }
+
+        // Release the interface and set to NULL
+        void Release() throw()
+        {
+            if (_object)
+            {
+                // Cast to IInspectable (no QI)
+                IUnknown* pObject = *(IUnknown**)(&_object);
+                // Set * to null without release
+                *(IUnknown**)(&_object) = nullptr;
+
+                ULONG_PTR currentContextToken;
+                __abi_ThrowIfFailed(CoGetContextToken(&currentContextToken));
+                if (_contextToken == 0 || _contextCallback == nullptr || _contextToken == currentContextToken)
+                {
+                    pObject->Release();
+                }
+                else
+                {
+                    Details::ReleaseInContext(pObject, _contextCallback.Get());
+                }
+                _contextCallback = nullptr;
+                _contextToken = 0;
+#if _MSC_VER >= 1800
+                _agileState = AgileState::Unknown;
+#endif
+            }
+        }
+
+        bool operator==(nullptr_t) const throw()
+        {
+            return _object == nullptr;
+        }
+
+        bool operator==(const Agile& other) const throw()
+        {
+            return _object == other._object && _contextToken == other._contextToken;
+        }
+
+        bool operator<(const Agile& other) const throw()
+        {
+            if (reinterpret_cast<void*>(_object) < reinterpret_cast<void*>(other._object))
+            {
+                return true;
+            }
+
+            return _object == other._object && _contextToken < other._contextToken;
+        }
+    };
+
+    template <typename T>
+    class Agile<T, false>
+    {
+        static_assert(__is_win_class(typename Details::AgileTypeHelper<T>::type) || __is_win_interface(typename Details::AgileTypeHelper<T>::type), "Agile can only be used with ref class or interface class types");
+        typename typedef Details::AgileTypeHelper<T>::agileMemberType TypeT;
+        TypeT _object;
+
+    public:
+        Agile() throw() : _object(nullptr)
+        {
+        }
+
+        Agile(nullptr_t) throw() : _object(nullptr)
+        {
+        }
+
+        explicit Agile(TypeT object) throw() : _object(object)
+        {
+        }
+
+        Agile(const Agile& object) throw() : _object(object._object)
+        {
+        }
+
+        Agile(Agile&& object) throw() : _object(nullptr)
+        {
+            Swap(object);
+        }
+
+        ~Agile() throw()
+        {
+            Release();
+        }
+
+        TypeT Get() const
+        {
+            return _object;
+        }
+
+        TypeT* GetAddressOf() throw()
+        {
+            Release();
+            return &_object;
+        }
+
+        TypeT* GetAddressOfForInOut() throw()
+        {
+            return &_object;
+        }
+
+        TypeT operator->() const throw()
+        {
+            return Get();
+        }
+
+        Agile& operator=(nullptr_t) throw()
+        {
+            Release();
+            return *this;
+        }
+
+        Agile& operator=(TypeT object) throw()
+        {
+            if (_object != object)
+            {
+                _object = object;
+            }
+            return *this;
+        }
+
+        Agile& operator=(Agile object) throw()
+        {
+            object.Swap(*this);
+            return *this;
+        }
+
+#if _MSC_VER < 1800
+        Agile& operator=(IUnknown* lp) throw()
+        {
+            Release();
+            // bump ref count
+            ::Microsoft::WRL::ComPtr<IUnknown> spObject(lp);
+
+            // put it into Platform Object
+            Platform::Object object;
+            *(IUnknown**)(&object) = spObject.Detach();
+
+            _object = object;
+            return *this;
+        }
+#endif
+
+        // Release the interface and set to NULL
+        void Release() throw()
+        {
+            _object = nullptr;
+        }
+
+        void Swap(Agile& object)
+        {
+            std::swap(_object, object._object);
+        }
+
+        bool operator==(nullptr_t) const throw()
+        {
+            return _object == nullptr;
+        }
+
+        bool operator==(const Agile& other) const throw()
+        {
+            return _object == other._object;
+        }
+
+        bool operator<(const Agile& other) const throw()
+        {
+            return reinterpret_cast<void*>(_object) < reinterpret_cast<void*>(other._object);
+        }
+    };
+
+#pragma warning(pop)
+
+    template<class U>
+    bool operator==(nullptr_t, const Agile<U>& a) throw()
+    {
+        return a == nullptr;
+    }
+
+    template<class U>
+    bool operator!=(const Agile<U>& a, nullptr_t) throw()
+    {
+        return !(a == nullptr);
+    }
+
+    template<class U>
+    bool operator!=(nullptr_t, const Agile<U>& a) throw()
+    {
+        return !(a == nullptr);
+    }
+
+    template<class U>
+    bool operator!=(const Agile<U>& a, const Agile<U>& b) throw()
+    {
+        return !(a == b);
+    }
+
+
+#endif // _PLATFORM_AGILE_H_
index b1122ef..2a9ee20 100644 (file)
    Originaly licensed under The Code Project Open License (CPOL) 1.02:
    http://www.codeproject.com/info/cpol10.aspx
 */
+//require Windows 8 for some of the formats defined otherwise could baseline on lower version
+#if WINVER < _WIN32_WINNT_WIN7
+#undef WINVER
+#define WINVER _WIN32_WINNT_WIN7
+#endif
+#if defined _MSC_VER && _MSC_VER >= 1600
+    #define HAVE_CONCURRENCY
+#endif
 #include <windows.h>
 #include <guiddef.h>
 #include <mfidl.h>
 #include <Mfapi.h>
 #include <mfplay.h>
 #include <mfobjects.h>
+#include <tchar.h>
 #include <strsafe.h>
 #include <Mfreadwrite.h>
 #include <new>
 #pragma comment(lib, "Mfreadwrite")
 #pragma comment(lib, "MinCore_Downlevel")
 
-// for ComPtr usage
-#include <wrl/client.h>
-using namespace Microsoft::WRL;
-
 #include <mferror.h>
 
 #ifdef HAVE_WINRT
+    // for ComPtr usage
+#include <wrl/client.h>
 #ifdef __cplusplus_winrt
 #include <agile.h>
 #include <vccorlib.h>
@@ -89,10 +96,169 @@ using namespace Microsoft::WRL;
 #include <wrl\wrappers\corewrappers.h>
 #include <windows.media.capture.h>
 #include <windows.devices.enumeration.h>
+#ifdef HAVE_CONCURRENCY
 #include <concrt.h>
-#include <ppltasks.h>
+#ifndef __cplusplus_winrt
+__declspec(noreturn) void __stdcall __abi_WinRTraiseException(long);
+
+inline void __abi_ThrowIfFailed(long __hrArg)
+{
+    if (__hrArg < 0)
+    {
+        __abi_WinRTraiseException(__hrArg);
+    }
+}
+
+struct Guid
+{
+public:
+    Guid();
+    Guid(__rcGUID_t);
+    operator ::__rcGUID_t();
+    bool Equals(Guid __guidArg);
+    bool Equals(__rcGUID_t __guidArg);
+    Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, unsigned __int8 __dArg,
+        unsigned __int8 __eArg, unsigned __int8 __fArg, unsigned __int8 __gArg, unsigned __int8 __hArg,
+        unsigned __int8 __iArg, unsigned __int8 __jArg, unsigned __int8 __kArg);
+    Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, const unsigned __int8* __dArg);
+private:
+    unsigned long  __a;
+    unsigned short __b;
+    unsigned short __c;
+    unsigned char __d;
+    unsigned char __e;
+    unsigned char __f;
+    unsigned char __g;
+    unsigned char __h;
+    unsigned char __i;
+    unsigned char __j;
+    unsigned char __k;
+};
+
+static_assert(sizeof(Guid) == sizeof(::_GUID), "Incorect size for Guid");
+static_assert(sizeof(__rcGUID_t) == sizeof(::_GUID), "Incorect size for __rcGUID_t");
+
+////////////////////////////////////////////////////////////////////////////////
+inline Guid::Guid() : __a(0), __b(0), __c(0), __d(0), __e(0), __f(0), __g(0), __h(0), __i(0), __j(0), __k(0)
+{
+}
+
+inline Guid::Guid(__rcGUID_t __guid) :
+__a(reinterpret_cast<const __s_GUID&>(__guid).Data1),
+__b(reinterpret_cast<const __s_GUID&>(__guid).Data2),
+__c(reinterpret_cast<const __s_GUID&>(__guid).Data3),
+__d(reinterpret_cast<const __s_GUID&>(__guid).Data4[0]),
+__e(reinterpret_cast<const __s_GUID&>(__guid).Data4[1]),
+__f(reinterpret_cast<const __s_GUID&>(__guid).Data4[2]),
+__g(reinterpret_cast<const __s_GUID&>(__guid).Data4[3]),
+__h(reinterpret_cast<const __s_GUID&>(__guid).Data4[4]),
+__i(reinterpret_cast<const __s_GUID&>(__guid).Data4[5]),
+__j(reinterpret_cast<const __s_GUID&>(__guid).Data4[6]),
+__k(reinterpret_cast<const __s_GUID&>(__guid).Data4[7])
+{
+}
+
+inline Guid::operator ::__rcGUID_t()
+{
+    return reinterpret_cast<__rcGUID_t>(*this);
+}
+
+inline bool Guid::Equals(Guid __guidArg)
+{
+    return *this == __guidArg;
+}
+
+inline bool Guid::Equals(__rcGUID_t __guidArg)
+{
+    return *this == static_cast< Guid>(__guidArg);
+}
+
+inline bool operator==(Guid __aArg, Guid __bArg)
+{
+    auto __a = reinterpret_cast<unsigned long*>(&__aArg);
+    auto __b = reinterpret_cast<unsigned long*>(&__bArg);
+
+    return (__a[0] == __b[0] && __a[1] == __b[1] && __a[2] == __b[2] && __a[3] == __b[3]);
+}
+
+inline bool operator!=(Guid __aArg, Guid __bArg)
+{
+    return !(__aArg == __bArg);
+}
+
+inline bool operator<(Guid __aArg, Guid __bArg)
+{
+    auto __a = reinterpret_cast<unsigned long*>(&__aArg);
+    auto __b = reinterpret_cast<unsigned long*>(&__bArg);
+
+    if (__a[0] != __b[0])
+    {
+        return __a[0] < __b[0];
+    }
+
+    if (__a[1] != __b[1])
+    {
+        return __a[1] < __b[1];
+    }
 
-using namespace Microsoft::WRL::Wrappers;
+    if (__a[2] != __b[2])
+    {
+        return __a[2] < __b[2];
+    }
+
+    if (__a[3] != __b[3])
+    {
+        return __a[3] < __b[3];
+    }
+
+    return false;
+}
+
+inline Guid::Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, unsigned __int8 __dArg,
+    unsigned __int8 __eArg, unsigned __int8 __fArg, unsigned __int8 __gArg, unsigned __int8 __hArg,
+    unsigned __int8 __iArg, unsigned __int8 __jArg, unsigned __int8 __kArg) :
+    __a(__aArg), __b(__bArg), __c(__cArg), __d(__dArg), __e(__eArg), __f(__fArg), __g(__gArg), __h(__hArg), __i(__iArg), __j(__jArg), __k(__kArg)
+{
+}
+
+inline Guid::Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, const unsigned __int8 __dArg[8]) :
+__a(__aArg), __b(__bArg), __c(__cArg)
+{
+    __d = __dArg[0];
+    __e = __dArg[1];
+    __f = __dArg[2];
+    __g = __dArg[3];
+    __h = __dArg[4];
+    __i = __dArg[5];
+    __j = __dArg[6];
+    __k = __dArg[7];
+}
+
+__declspec(selectany) Guid __winrt_GUID_NULL(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+//
+//// Don't want to define the real IUnknown from unknown.h here. That would means if the user has
+//// any broken code that uses it, compile errors will take the form of e.g.:
+////     predefined C++ WinRT types (compiler internal)(41) : see declaration of 'IUnknown::QueryInterface'
+//// This is not helpful. If they use IUnknown, we still need to point them to the actual unknown.h so
+//// that they can see the original definition.
+////
+//// For WinRT, we'll instead have a parallel COM interface hierarchy for basic interfaces starting with _.
+//// The type mismatch is not an issue. COM passes types through GUID / void* combos - the original type
+//// doesn't come into play unless the user static_casts an implementation type to one of these, but
+//// the WinRT implementation types are hidden.
+__interface __declspec(uuid("00000000-0000-0000-C000-000000000046")) __abi_IUnknown
+{
+public:
+    virtual long __stdcall __abi_QueryInterface(Guid&, void**) = 0;
+    virtual unsigned long __stdcall __abi_AddRef() = 0;
+    virtual unsigned long __stdcall __abi_Release() = 0;
+};
+#endif
+#include "ppltasks_winrt.h"
+#endif
+#else
+#include <atlbase.h>
 #endif
 
 struct IMFMediaType;
@@ -114,18 +280,23 @@ template <class T> void SafeRelease(T **ppT)
     }
 }
 
-/// Class for printing info into consol
-class DebugPrintOut
+#ifdef _DEBUG
+/// Class for printing info into console
+class DPO
 {
 public:
-    ~DebugPrintOut(void);
-    static DebugPrintOut& getInstance();
+    ~DPO(void);
+    static DPO& getInstance();
     void printOut(const wchar_t *format, ...);
     void setVerbose(bool state);
     bool verbose;
 private:
-    DebugPrintOut(void);
+    DPO(void);
 };
+#define DebugPrintOut(...) DPO::getInstance().printOut(__VA_ARGS__)
+#else
+#define DebugPrintOut(...) void()
+#endif
 
 #include "cap_msmf.hpp"
 
@@ -227,7 +398,9 @@ protected:
     RawImage *ig_RIFirst;
     RawImage *ig_RISecond;
     RawImage *ig_RIOut;
-};
+private:
+    ImageGrabberCallback& operator=(const ImageGrabberCallback&);   // Declared to fix compilation warning.
+ };
 
 #ifdef HAVE_WINRT
 extern const __declspec(selectany) WCHAR RuntimeClass_CV_ImageGrabberWinRT[] = L"cv.ImageGrabberWinRT";
@@ -271,7 +444,7 @@ class ImageGrabber : public ImageGrabberCallback
 {
 public:
     ~ImageGrabber(void);
-    HRESULT initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat);
+    HRESULT initImageGrabber(IMFMediaSource *pSource);
     HRESULT startGrabbing(void);
     void stopGrabbing();
     // IUnknown methods
@@ -292,6 +465,8 @@ private:
     HRESULT AddSourceNode(IMFTopology *pTopology, IMFMediaSource *pSource,
         IMFPresentationDescriptor *pPD, IMFStreamDescriptor *pSD, IMFTopologyNode **ppNode);
     HRESULT AddOutputNode(IMFTopology *pTopology, IMFActivate *pActivate, DWORD dwId, IMFTopologyNode **ppNode);
+
+    ImageGrabber& operator=(const ImageGrabber&);   // Declared to fix comiplation error.
 };
 
 /// Class for controlling of thread of the grabbing raw data from video device
@@ -373,8 +548,9 @@ public:
     void waitForDevice()
     {
         if (vd_pAction) {
-            HRESULT hr;
-            DO_ACTION_SYNCHRONOUSLY(hr, vd_pAction, GET_CURRENT_CONTEXT);
+#ifdef HAVE_CONCURRENCY
+            CREATE_TASK DEFINE_RET_TYPE(void)(vd_pAction).wait();
+#endif
             vd_pAction = nullptr;
         }
     }
@@ -385,6 +561,7 @@ public:
     int getCountFormats();
     unsigned int getWidth();
     unsigned int getHeight();
+    unsigned int getFrameRate() const;
     MediaType getFormat(unsigned int id);
     bool setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate = 0);
     bool setupDevice(unsigned int id);
@@ -406,6 +583,7 @@ private:
     CamParametrs vd_PrevParametrs;
     unsigned int vd_Width;
     unsigned int vd_Height;
+    unsigned int vd_FrameRate;
     unsigned int vd_CurrentNumber;
     bool vd_IsSetuped;
     std::map<UINT64, FrameRateMap> vd_CaptureFormats;
@@ -413,11 +591,13 @@ private:
     IMFMediaSource *vd_pSource;
 #ifdef HAVE_WINRT
     MAKE_WRL_AGILE_REF(_MediaCapture) vd_pMedCap;
-    IMedCapFailHandler* vd_pMedCapFail;
+    EventRegistrationToken vd_cookie;
     ImageGrabberWinRT *vd_pImGr;
     MAKE_WRL_REF(_AsyncAction) vd_pAction;
+#ifdef HAVE_CONCURRENCY
     Concurrency::critical_section vd_lock;
 #endif
+#endif
     emergensyStopEventCallback vd_func;
     void *vd_userData;
     HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
@@ -428,7 +608,9 @@ private:
     HRESULT enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource);
     long setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned long dwFormatIndex, MAKE_WRL_REF(_AsyncAction)* pAction);
     long resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice);
-    long checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice);
+#ifdef HAVE_CONCURRENCY
+    long checkDevice(_DeviceClass devClass, DEFINE_TASK<void>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice);
+#endif
 #else
     long resetDevice(IMFActivate *pActivate);
     long checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice);
@@ -445,8 +627,9 @@ public:
     long initDevices(_DeviceClass devClass);
     void waitInit() {
         if (vds_enumTask) {
-            HRESULT hr;
-            DO_ACTION_SYNCHRONOUSLY(hr, vds_enumTask, GET_CURRENT_CONTEXT);
+#ifdef HAVE_CONCURRENCY
+            CREATE_TASK DEFINE_RET_TYPE(void)(vds_enumTask).wait();
+#endif
             vds_enumTask = nullptr;
         }
     }
@@ -502,6 +685,8 @@ public:
     unsigned int getWidth(int deviceID);
     // Getting height of image, which is getting from videodevice with deviceID
     unsigned int getHeight(int deviceID);
+    // Getting frame rate, which is getting from videodevice with deviceID
+    unsigned int getFrameRate(int deviceID) const;
     // Getting name of videodevice with deviceID
     wchar_t *getNameVideoDevice(int deviceID);
     // Getting interface MediaSource for Media Foundation from videodevice with deviceID
@@ -516,8 +701,10 @@ public:
     bool isDeviceMediaSource(int deviceID);
     // Checking of using Raw Data of pixels from videodevice with deviceID
     bool isDeviceRawDataSource(int deviceID);
+#ifdef _DEBUG
     // Setting of the state of outprinting info in console
     static void setVerbose(bool state);
+#endif
     // Initialization of video device with deviceID by media type with id
     bool setupDevice(int deviceID, unsigned int id = 0);
     // Initialization of video device with deviceID by wisth w, height h and fps idealFramerate
@@ -536,21 +723,22 @@ private:
     void updateListOfDevices();
 };
 
-DebugPrintOut::DebugPrintOut(void):verbose(true)
+#ifdef _DEBUG
+DPO::DPO(void):verbose(true)
 {
 }
 
-DebugPrintOut::~DebugPrintOut(void)
+DPO::~DPO(void)
 {
 }
 
-DebugPrintOut& DebugPrintOut::getInstance()
+DPO& DPO::getInstance()
 {
-    static DebugPrintOut instance;
+    static DPO instance;
     return instance;
 }
 
-void DebugPrintOut::printOut(const wchar_t *format, ...)
+void DPO::printOut(const wchar_t *format, ...)
 {
     if(verbose)
     {
@@ -558,23 +746,33 @@ void DebugPrintOut::printOut(const wchar_t *format, ...)
         wchar_t *p = NULL;
         va_list args;
         va_start(args, format);
-        if(wcscmp(format, L"%i"))
+        if( ::IsDebuggerPresent() )
         {
-            i = va_arg (args, int);
+            WCHAR szMsg[512];
+            ::StringCchVPrintfW(szMsg, sizeof(szMsg)/sizeof(szMsg[0]), format, args);
+            ::OutputDebugStringW(szMsg);
         }
-        if(wcscmp(format, L"%s"))
+        else
         {
-            p = va_arg (args, wchar_t *);
+            if(wcscmp(format, L"%i"))
+            {
+                i = va_arg (args, int);
+            }
+            if(wcscmp(format, L"%s"))
+            {
+                p = va_arg (args, wchar_t *);
+            }
+            wprintf(format, i,p);
         }
-        wprintf(format, i,p);
         va_end (args);
     }
 }
 
-void DebugPrintOut::setVerbose(bool state)
+void DPO::setVerbose(bool state)
 {
     verbose = state;
 }
+#endif
 
 LPCWSTR GetGUIDNameConstNew(const GUID& guid);
 HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz);
@@ -650,7 +848,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType
                 hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
                 if (SUCCEEDED(hr))
                 {
-                    out.MF_MT_AM_FORMAT_TYPE = MF_MT_AM_FORMAT_TYPE;
+                    out.MF_MT_AM_FORMAT_TYPE = *var.puuid;
                     out.pMF_MT_AM_FORMAT_TYPEName = pGuidValName;
                     pGuidValName = NULL;
                 }
@@ -660,7 +858,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType
                 hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
                 if (SUCCEEDED(hr))
                 {
-                    out.MF_MT_MAJOR_TYPE = MF_MT_MAJOR_TYPE;
+                    out.MF_MT_MAJOR_TYPE = *var.puuid;
                     out.pMF_MT_MAJOR_TYPEName = pGuidValName;
                     pGuidValName = NULL;
                 }
@@ -670,7 +868,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType
                 hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
                 if (SUCCEEDED(hr))
                 {
-                    out.MF_MT_SUBTYPE = MF_MT_SUBTYPE;
+                    out.MF_MT_SUBTYPE = *var.puuid;
                     out.pMF_MT_SUBTYPEName = pGuidValName;
                     pGuidValName = NULL;
                 }
@@ -963,9 +1161,8 @@ FormatReader::FormatReader(void)
 MediaType FormatReader::Read(IMFMediaType *pType)
 {
     UINT32 count = 0;
-    HRESULT hr = S_OK;
     MediaType out;
-    hr = pType->LockStore();
+    HRESULT hr = pType->LockStore();
     if (FAILED(hr))
     {
         return out;
@@ -1032,9 +1229,8 @@ ImageGrabber::~ImageGrabber(void)
 
     SafeRelease(&ig_pSession);
     SafeRelease(&ig_pTopology);
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
 
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroying instance of the ImageGrabber class\n", ig_DeviceID);
+    DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroying instance of the ImageGrabber class\n", ig_DeviceID);
 }
 
 #ifdef HAVE_WINRT
@@ -1063,9 +1259,7 @@ ImageGrabberWinRT::~ImageGrabberWinRT(void)
         CloseHandle(ig_hFrameGrabbed);
     }
 
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE: Destroying instance of the ImageGrabberWinRT class\n");
+    DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE: Destroying instance of the ImageGrabberWinRT class\n");
 }
 
 HRESULT ImageGrabberWinRT::initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource,
@@ -1082,7 +1276,7 @@ HRESULT ImageGrabberWinRT::initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource,
     if (FAILED(hr)) return hr;
     GET_WRL_OBJ_FROM_OBJ(_VideoEncodingProperties, pVidProps, pMedEncProps, hr);
     if (FAILED(hr)) return hr;
-    ComPtr<IMFMediaType> pType = NULL;
+    _ComPtr<IMFMediaType> pType = NULL;
     hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType);
     if (FAILED(hr)) return hr;
     MediaType MT = FormatReader::Read(pType.Get());
@@ -1113,13 +1307,17 @@ HRESULT ImageGrabberWinRT::stopGrabbing(MAKE_WRL_REF(_AsyncAction)* action)
         MAKE_WRL_REF(_AsyncAction) pAction;
         WRL_METHOD_BASE(imedPrevCap, StopPreviewAsync, pAction, hr)
         if (SUCCEEDED(hr)) {
-            SAVE_CURRENT_CONTEXT(context);
-            *action = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, context, this)
-                HRESULT hr;
-                DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
+#ifdef HAVE_CONCURRENCY
+            DEFINE_TASK<void> _task = CREATE_TASK DEFINE_RET_TYPE(void)(pAction);
+            *action = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, _task, this)
+                HRESULT hr = S_OK;
+                _task.wait();
                 SafeRelease(&ig_pMediaSink);
                 SetEvent(ig_hFinish);
             END_CREATE_ASYNC(hr));
+#else
+            *action = nullptr;
+#endif
         }
     }
     return hr;
@@ -1180,21 +1378,19 @@ HRESULT ImageGrabberWinRT::CreateInstance(ImageGrabberWinRT **ppIG, bool synchro
     {
         return E_OUTOFMEMORY;
     }
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE: Creating instance of ImageGrabberWinRT\n");
+    DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE: Creating instance of ImageGrabberWinRT\n");
     return S_OK;
 }
 #endif
 
-HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat)
+HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource)
 {
-    ComPtr<IMFActivate> pSinkActivate = NULL;
-    ComPtr<IMFMediaType> pType = NULL;
-    ComPtr<IMFPresentationDescriptor> pPD = NULL;
-    ComPtr<IMFStreamDescriptor> pSD = NULL;
-    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
-    ComPtr<IMFMediaType> pCurrentType = NULL;
-    HRESULT hr = S_OK;
+    _ComPtr<IMFActivate> pSinkActivate = NULL;
+    _ComPtr<IMFMediaType> pType = NULL;
+    _ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    _ComPtr<IMFStreamDescriptor> pSD = NULL;
+    _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    _ComPtr<IMFMediaType> pCurrentType = NULL;
     MediaType MT;
      // Clean up.
     if (ig_pSession)
@@ -1204,7 +1400,7 @@ HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat
     SafeRelease(&ig_pSession);
     SafeRelease(&ig_pTopology);
     ig_pSource = pSource;
-    hr = pSource->CreatePresentationDescriptor(&pPD);
+    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
     if (FAILED(hr))
     {
         goto err;
@@ -1232,25 +1428,16 @@ HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat
         MT = FormatReader::Read(pCurrentType.Get());
     }
 err:
-    unsigned int sizeRawImage = 0;
-    if(VideoFormat == MFVideoFormat_RGB24)
-    {
-        sizeRawImage = MT.MF_MT_FRAME_SIZE * 3;
-    }
-    else if(VideoFormat == MFVideoFormat_RGB32)
-    {
-        sizeRawImage = MT.MF_MT_FRAME_SIZE * 4;
-    }
-    //sizeRawImage = MT.MF_MT_SAMPLE_SIZE;
-    CHECK_HR(hr = RawImage::CreateInstance(&ig_RIFirst, sizeRawImage));
-    CHECK_HR(hr = RawImage::CreateInstance(&ig_RISecond, sizeRawImage));
+    CHECK_HR(hr);
+    CHECK_HR(hr = RawImage::CreateInstance(&ig_RIFirst, MT.MF_MT_SAMPLE_SIZE));
+    CHECK_HR(hr = RawImage::CreateInstance(&ig_RISecond, MT.MF_MT_SAMPLE_SIZE));
     ig_RIOut = ig_RISecond;
     // Configure the media type that the Sample Grabber will receive.
     // Setting the major and subtype is usually enough for the topology loader
     // to resolve the topology.
     CHECK_HR(hr = MFCreateMediaType(pType.GetAddressOf()));
-    CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
-    CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, VideoFormat));
+    CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MT.MF_MT_MAJOR_TYPE));
+    CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, MT.MF_MT_SUBTYPE));
     // Create the sample grabber sink.
     CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType.Get(), this, pSinkActivate.GetAddressOf()));
     // To run as fast as possible, set this attribute (requires Windows 7):
@@ -1277,19 +1464,16 @@ void ImageGrabber::stopGrabbing()
 {
     if(ig_pSession)
         ig_pSession->Stop();
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID);
+    DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID);
 }
 
 HRESULT ImageGrabber::startGrabbing(void)
 {
-    HRESULT hr = S_OK;
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    ComPtr<IMFMediaEvent> pEvent = NULL;
+    _ComPtr<IMFMediaEvent> pEvent = NULL;
     PROPVARIANT var;
     PropVariantInit(&var);
-    hr = ig_pSession->SetTopology(0, ig_pTopology);
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images\n", ig_DeviceID);
+    HRESULT hr = ig_pSession->SetTopology(0, ig_pTopology);
+    DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images\n", ig_DeviceID);
     hr = ig_pSession->Start(&GUID_NULL, &var);
     for(;;)
     {
@@ -1316,28 +1500,28 @@ HRESULT ImageGrabber::startGrabbing(void)
         }
         if (met == MESessionEnded)
         {
-            DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionEnded \n", ig_DeviceID);
+            DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionEnded\n", ig_DeviceID);
             ig_pSession->Stop();
             break;
         }
         if (met == MESessionStopped)
         {
-            DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID);
+            DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID);
             break;
         }
         if (met == MEVideoCaptureDeviceRemoved)
         {
-            DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID);
+            DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID);
             break;
         }
         if ((met == MEError) || (met == MENonFatalError))
         {
             pEvent->GetStatus(&hrStatus);
-            DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEError | MENonFatalError: %u\n", ig_DeviceID, hrStatus);
+            DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MEError | MENonFatalError: %u\n", ig_DeviceID, hrStatus);
             break;
         }
     }
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID);
+    DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID);
 
 done:
     SetEvent(ig_hFinish);
@@ -1356,11 +1540,11 @@ void ImageGrabberCallback::resumeGrabbing()
 HRESULT ImageGrabber::CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo)
 {
     IMFTopology* pTopology = NULL;
-    ComPtr<IMFPresentationDescriptor> pPD = NULL;
-    ComPtr<IMFStreamDescriptor> pSD = NULL;
-    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
-    ComPtr<IMFTopologyNode> pNode1 = NULL;
-    ComPtr<IMFTopologyNode> pNode2 = NULL;
+    _ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    _ComPtr<IMFStreamDescriptor> pSD = NULL;
+    _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    _ComPtr<IMFTopologyNode> pNode1 = NULL;
+    _ComPtr<IMFTopologyNode> pNode2 = NULL;
     HRESULT hr = S_OK;
     DWORD cStreams = 0;
     CHECK_HR(hr = MFCreateTopology(&pTopology));
@@ -1400,7 +1584,7 @@ HRESULT ImageGrabber::AddSourceNode(
     IMFStreamDescriptor *pSD,         // Stream descriptor.
     IMFTopologyNode **ppNode)         // Receives the node pointer.
 {
-    ComPtr<IMFTopologyNode> pNode = NULL;
+    _ComPtr<IMFTopologyNode> pNode = NULL;
     HRESULT hr = S_OK;
     CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, pNode.GetAddressOf()));
     CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource));
@@ -1421,7 +1605,7 @@ HRESULT ImageGrabber::AddOutputNode(
     DWORD dwId,                 // Identifier of the stream sink.
     IMFTopologyNode **ppNode)   // Receives the node pointer.
 {
-    ComPtr<IMFTopologyNode> pNode = NULL;
+    _ComPtr<IMFTopologyNode> pNode = NULL;
     HRESULT hr = S_OK;
     CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, pNode.GetAddressOf()));
     CHECK_HR(hr = pNode->SetObject(pActivate));
@@ -1443,8 +1627,7 @@ HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID,
     {
         return E_OUTOFMEMORY;
     }
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Creating instance of ImageGrabber\n", deviceID);
+    DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Creating instance of ImageGrabber\n", deviceID);
     return S_OK;
 }
 
@@ -1537,7 +1720,7 @@ STDMETHODIMP ImageGrabberCallback::OnProcessSample(REFGUID guidMajorMediaType, D
     DWORD status = WaitForMultipleObjects(2, tmp, FALSE, INFINITE);
     if (status == WAIT_OBJECT_0)
     {
-        printf("OnProcessFrame called after ig_hFinish event\n");
+        DebugPrintOut(L"OnProcessFrame called after ig_hFinish event\n");
         return S_OK;
     }
 
@@ -1584,15 +1767,14 @@ DWORD WINAPI MainThreadFunction( LPVOID lpParam )
 
 HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID, bool synchronious)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     *ppIGT = new (std::nothrow) ImageGrabberThread(pSource, deviceID, synchronious);
     if (ppIGT == NULL)
     {
-        DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Memory cannot be allocated\n", deviceID);
+        DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Memory cannot be allocated\n", deviceID);
         return E_OUTOFMEMORY;
     }
     else
-        DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Creating of the instance of ImageGrabberThread\n", deviceID);
+        DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Creating of the instance of ImageGrabberThread\n", deviceID);
     return S_OK;
 }
 
@@ -1601,24 +1783,23 @@ ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int dev
     igt_Handle(NULL),
     igt_stop(false)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     HRESULT hr = ImageGrabber::CreateInstance(&igt_pImageGrabber, deviceID, synchronious);
     igt_DeviceID = deviceID;
     if(SUCCEEDED(hr))
     {
-        hr = igt_pImageGrabber->initImageGrabber(pSource, MFVideoFormat_RGB24);
+        hr = igt_pImageGrabber->initImageGrabber(pSource);
         if(!SUCCEEDED(hr))
         {
-            DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with initialization of the instance of the ImageGrabber class\n", deviceID);
+            DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with initialization of the instance of the ImageGrabber class\n", deviceID);
         }
         else
         {
-            DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Initialization of instance of the ImageGrabber class\n", deviceID);
+            DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Initialization of instance of the ImageGrabber class\n", deviceID);
         }
     }
     else
     {
-        DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with creation of the instance of the ImageGrabber class\n", deviceID);
+        DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with creation of the instance of the ImageGrabber class\n", deviceID);
     }
 }
 
@@ -1633,8 +1814,7 @@ void ImageGrabberThread::setEmergencyStopEvent(void *userData, void(*func)(int,
 
 ImageGrabberThread::~ImageGrabberThread(void)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Destroing ImageGrabberThread\n", igt_DeviceID);
+    DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Destroing ImageGrabberThread\n", igt_DeviceID);
     if (igt_Handle)
         WaitForSingleObject(igt_Handle, INFINITE);
     delete igt_pImageGrabber;
@@ -1662,30 +1842,29 @@ void ImageGrabberThread::start()
 
 void ImageGrabberThread::run()
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if(igt_pImageGrabber)
     {
-        DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Thread for grabbing images is started\n", igt_DeviceID);
+        DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Thread for grabbing images is started\n", igt_DeviceID);
         HRESULT hr = igt_pImageGrabber->startGrabbing();
         if(!SUCCEEDED(hr))
         {
-            DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with starting the process of grabbing\n", igt_DeviceID);
+            DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with starting the process of grabbing\n", igt_DeviceID);
         }
     }
     else
     {
-        DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i The thread is finished without execution of grabbing\n", igt_DeviceID);
+        DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i The thread is finished without execution of grabbing\n", igt_DeviceID);
     }
     if(!igt_stop)
     {
-        DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Emergency Stop thread\n", igt_DeviceID);
+        DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Emergency Stop thread\n", igt_DeviceID);
         if(igt_func)
         {
             igt_func(igt_DeviceID, igt_userData);
         }
     }
     else
-        DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Finish thread\n", igt_DeviceID);
+        DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Finish thread\n", igt_DeviceID);
 }
 
 ImageGrabber *ImageGrabberThread::getImageGrabber()
@@ -1698,8 +1877,7 @@ Media_Foundation::Media_Foundation(void)
     HRESULT hr = MFStartup(MF_VERSION);
     if(!SUCCEEDED(hr))
     {
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MEDIA FOUNDATION: It cannot be created!!!\n");
+        DebugPrintOut(L"MEDIA FOUNDATION: It cannot be created!!!\n");
     }
 }
 
@@ -1708,8 +1886,7 @@ Media_Foundation::~Media_Foundation(void)
     HRESULT hr = MFShutdown();
     if(!SUCCEEDED(hr))
     {
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MEDIA FOUNDATION: Resources cannot be released\n");
+        DebugPrintOut(L"MEDIA FOUNDATION: Resources cannot be released\n");
     }
 }
 
@@ -1720,7 +1897,7 @@ bool Media_Foundation::buildListOfDevices()
     videoDevices *vDs = &videoDevices::getInstance();
     hr = vDs->initDevices(WRL_ENUM_GET(_DeviceClass, DeviceClass, VideoCapture));
 #else
-    ComPtr<IMFAttributes> pAttributes = NULL;
+    _ComPtr<IMFAttributes> pAttributes = NULL;
     CoInitialize(NULL);
     hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
     if (SUCCEEDED(hr))
@@ -1738,8 +1915,7 @@ bool Media_Foundation::buildListOfDevices()
 #endif
     if (FAILED(hr))
     {
-       DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-       DPO->printOut(L"MEDIA FOUNDATION: The access to the video cameras denied\n");
+       DebugPrintOut(L"MEDIA FOUNDATION: The access to the video cameras denied\n");
     }
 
     return (SUCCEEDED(hr));
@@ -1803,11 +1979,11 @@ unsigned char * RawImage::getpPixels()
 }
 
 videoDevice::videoDevice(void): vd_IsSetuped(false), vd_LockOut(OpenLock), vd_pFriendlyName(NULL),
-    vd_Width(0), vd_Height(0), vd_pSource(NULL), vd_pImGrTh(NULL), vd_func(NULL), vd_userData(NULL)
+    vd_Width(0), vd_Height(0), vd_FrameRate(0), vd_pSource(NULL), vd_pImGrTh(NULL), vd_func(NULL), vd_userData(NULL)
 {
 #ifdef HAVE_WINRT
     vd_pMedCap = nullptr;
-    vd_pMedCapFail = NULL;
+    vd_cookie.value = 0;
     vd_pImGr = NULL;
     vd_pAction = nullptr;
 #endif
@@ -1899,7 +2075,7 @@ long videoDevice::resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice)
 long videoDevice::resetDevice(IMFActivate *pActivate)
 #endif
 {
-    HRESULT hr = -1;
+    HRESULT hr = E_FAIL;
     vd_CurrentFormats.clear();
     if(vd_pFriendlyName)
         CoTaskMemFree(vd_pFriendlyName);
@@ -1926,25 +2102,28 @@ long videoDevice::resetDevice(IMFActivate *pActivate)
         if (FAILED(hr)) return hr;
         MAKE_WRL_REF(_AsyncAction) pAction;
         WRL_METHOD(DEREF_WRL_OBJ(pIMedCap), _InitializeWithSettingsAsync, pAction, hr, DEREF_WRL_OBJ(pCapInitSet))
+#ifdef HAVE_CONCURRENCY
+        DEFINE_TASK<void> _task = CREATE_TASK DEFINE_RET_TYPE(void)(pAction);
         if (FAILED(hr)) return hr;
         MAKE_WRL_AGILE_REF(_MediaCapture) pAgileMedCap;
         pAgileMedCap = PREPARE_TRANSFER_WRL_OBJ(pIMedCap);
         Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
         MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
         SAVE_CURRENT_CONTEXT(context);
-        vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, pOldAction, context, &pAgileMedCap, this)
-           HRESULT hr;
-           if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
-           DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
+        vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, _task, pOldAction, context, &pAgileMedCap, this)
+           HRESULT hr = S_OK;
+           if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
+           _task.wait();
            if (SUCCEEDED(hr)) {
                 //all camera capture calls only in original context
                 BEGIN_CALL_IN_CONTEXT(hr, context, pAgileMedCap, this)
                     enumerateCaptureFormats(DEREF_AGILE_WRL_OBJ(pAgileMedCap));
-                END_CALL_IN_CONTEXT(S_OK)
+                END_CALL_IN_CONTEXT_BASE
            }
            buildLibraryofTypes();
            RELEASE_AGILE_WRL(pAgileMedCap)
         END_CREATE_ASYNC(hr));
+#endif
     }
 #else
     if(pActivate)
@@ -1965,8 +2144,7 @@ long videoDevice::resetDevice(IMFActivate *pActivate)
         if(FAILED(hr))
         {
             vd_pFriendlyName = NULL;
-            DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-            DPO->printOut(L"VIDEODEVICE %i: IMFMediaSource interface cannot be created \n", vd_CurrentNumber);
+            DebugPrintOut(L"VIDEODEVICE %i: IMFMediaSource interface cannot be created \n", vd_CurrentNumber);
         }
     }
 #endif
@@ -1984,15 +2162,14 @@ long videoDevice::readInfoOfDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice, un
 #else
 long videoDevice::readInfoOfDevice(IMFActivate *pActivate, unsigned int Num)
 {
-    HRESULT hr = -1;
     vd_CurrentNumber = Num;
-    hr = resetDevice(pActivate);
-    return hr;
+    return resetDevice(pActivate);
 }
 #endif
 
 #ifdef HAVE_WINRT
-long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice)
+#ifdef HAVE_CONCURRENCY
+long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<void>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice)
 {
     HRESULT hr = S_OK;
     ACTIVATE_STATIC_OBJ(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation, MAKE_WRL_OBJ(_DeviceInformationStatics), pDevStat, hr)
@@ -2000,10 +2177,10 @@ long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask
     MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction;
     WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass)
     if (SUCCEEDED(hr)) {
-        *pTask = CREATE_TASK([pAction, &ppDevice, this]() -> HRESULT {
-            HRESULT hr;
-            MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector;
-            DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, pAction, GET_CURRENT_CONTEXT, pVector, _VectorView, _DeviceInformation, _DeviceInformationCollection);
+        *pTask = CREATE_TASK DEFINE_RET_TYPE(void)([pAction, &ppDevice, this]() -> DEFINE_RET_FORMAL(void) {
+            HRESULT hr = S_OK;
+            MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector =
+                CREATE_TASK DEFINE_RET_TYPE(MAKE_WRL_REF(_VectorView<MAKE_WRL_REF(_DeviceInformation)>))(pAction).get();
             UINT32 count = 0;
             if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr)
             if (SUCCEEDED(hr) && count > 0) {
@@ -2021,20 +2198,19 @@ long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask
                     }
                 }
             }
-            return hr;
+            RET_VAL_BASE;
         });
     }
     return hr;
 }
+#endif
 #else
 long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
 {
-    HRESULT hr = S_OK;
     IMFActivate **ppDevices = NULL;
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     UINT32 count;
     wchar_t *newFriendlyName = NULL;
-    hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
+    HRESULT hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
     if (SUCCEEDED(hr))
     {
         if(count > 0)
@@ -2050,8 +2226,8 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
                 {
                     if(wcscmp(newFriendlyName, vd_pFriendlyName) != 0)
                     {
-                        DPO->printOut(L"VIDEODEVICE %i: Chosen device cannot be found \n", vd_CurrentNumber);
-                        hr = -1;
+                        DebugPrintOut(L"VIDEODEVICE %i: Chosen device cannot be found \n", vd_CurrentNumber);
+                        hr = E_INVALIDARG;
                         pDevice = NULL;
                     }
                     else
@@ -2062,13 +2238,13 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
                 }
                 else
                 {
-                    DPO->printOut(L"VIDEODEVICE %i: Name of device cannot be gotten \n", vd_CurrentNumber);
+                    DebugPrintOut(L"VIDEODEVICE %i: Name of device cannot be gotten \n", vd_CurrentNumber);
                 }
             }
             else
             {
-                DPO->printOut(L"VIDEODEVICE %i: Number of devices more than corrent number of the device \n", vd_CurrentNumber);
-                hr = -1;
+                DebugPrintOut(L"VIDEODEVICE %i: Number of devices more than corrent number of the device \n", vd_CurrentNumber);
+                hr = E_INVALIDARG;
             }
             for(UINT32 i = 0; i < count; i++)
             {
@@ -2077,11 +2253,11 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
             SafeRelease(ppDevices);
         }
         else
-            hr = -1;
+            hr = E_FAIL;
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE %i: List of DeviceSources cannot be enumerated \n", vd_CurrentNumber);
+        DebugPrintOut(L"VIDEODEVICE %i: List of DeviceSources cannot be enumerated \n", vd_CurrentNumber);
     }
     return hr;
 }
@@ -2092,19 +2268,20 @@ long videoDevice::initDevice()
     HRESULT hr = S_OK;
     CoInitialize(NULL);
 #ifdef HAVE_WINRT
+#ifdef HAVE_CONCURRENCY
     Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
     MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
     SAVE_CURRENT_CONTEXT(context);
-    vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pOldAction, context, this)
+    vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, pOldAction, context, this)
         HRESULT hr;
-        if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
-        DEFINE_TASK<HRESULT> pTask;
+        if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
+        DEFINE_TASK<void> pTask;
         MAKE_WRL_OBJ(_IDeviceInformation) pDevInfo;
         hr = checkDevice(WRL_ENUM_GET(_DeviceClass, DeviceClass, VideoCapture), &pTask, REF_WRL_OBJ(pDevInfo));
-        if (SUCCEEDED(hr)) hr = pTask.get();
+        if (SUCCEEDED(hr)) pTask.wait();
         if (SUCCEEDED(hr)) {
-            MAKE_WRL_REF(_AsyncAction) pAction;
-            BEGIN_CALL_IN_CONTEXT(hr, context, pDevInfo, &pAction, context, this)
+            DEFINE_TASK<void> _task;
+            BEGIN_CALL_IN_CONTEXT(hr, context, pDevInfo, &_task, context, this)
                 HRESULT hr;
                 ACTIVATE_OBJ(RuntimeClass_Windows_Media_Capture_MediaCapture, _MediaCapture, pIMedCap, hr)
                 if (SUCCEEDED(hr)) {
@@ -2120,24 +2297,24 @@ long videoDevice::initDevice()
                     }
                     if (SUCCEEDED(hr))
                         WRL_PROP_PUT(pCapInitSet, StreamingCaptureMode, WRL_ENUM_GET(_StreamingCaptureMode, StreamingCaptureMode, Video), hr)
-                    if (SUCCEEDED(hr)) {
-                        vd_pMedCapFail = create_medcapfailedhandler([this, context](){
+                    if (SUCCEEDED(hr)) reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap))->add_Failed(Microsoft::WRL::Callback<ABI::Windows::Media::Capture::IMediaCaptureFailedEventHandler>([this, context](ABI::Windows::Media::Capture::IMediaCapture*, ABI::Windows::Media::Capture::IMediaCaptureFailedEventArgs*) -> HRESULT {
                             HRESULT hr;
                             BEGIN_CALL_IN_CONTEXT(hr, context, this)
                                 closeDevice();
-                            END_CALL_IN_CONTEXT(S_OK)
-                        });
-                    }
-                    if (SUCCEEDED(hr)) hr = vd_pMedCapFail->AddHandler(reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap)));
-                    if (SUCCEEDED(hr)) WRL_METHOD(vd_pMedCap, _InitializeWithSettingsAsync, pAction, hr, DEREF_WRL_OBJ(pCapInitSet))
+                            END_CALL_IN_CONTEXT_BASE
+                            return hr;
+                        }).Get(), &vd_cookie);
+                    MAKE_WRL_OBJ(_AsyncAction) pAction;
+                    if (SUCCEEDED(hr)) WRL_METHOD(vd_pMedCap, _InitializeWithSettingsAsync, *REF_WRL_OBJ(pAction), hr, DEREF_WRL_OBJ(pCapInitSet))
+                    if (SUCCEEDED(hr)) _task = CREATE_TASK DEFINE_RET_TYPE(void)(DEREF_WRL_OBJ(pAction));
                 }
             END_CALL_IN_CONTEXT(hr)
-            DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
+            _task.wait();
         }
     END_CREATE_ASYNC(hr));
+#endif
 #else
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    ComPtr<IMFAttributes> pAttributes = NULL;
+    _ComPtr<IMFAttributes> pAttributes = NULL;
     IMFActivate *vd_pActivate = NULL;
     hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
     if (SUCCEEDED(hr))
@@ -2164,12 +2341,12 @@ long videoDevice::initDevice()
         }
         else
         {
-            DPO->printOut(L"VIDEODEVICE %i: Device there is not \n", vd_CurrentNumber);
+            DebugPrintOut(L"VIDEODEVICE %i: Device there is not \n", vd_CurrentNumber);
         }
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE %i: The attribute of video cameras cannot be getting \n", vd_CurrentNumber);
+        DebugPrintOut(L"VIDEODEVICE %i: The attribute of video cameras cannot be getting \n", vd_CurrentNumber);
     }
 #endif
     return hr;
@@ -2199,17 +2376,18 @@ void videoDevice::closeDevice()
         vd_IsSetuped = false;
 
 #ifdef HAVE_WINRT
+#ifdef HAVE_CONCURRENCY
         if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) {
             MAKE_WRL_REF(_AsyncAction) action;
             Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
             MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
             vd_pImGr->stopGrabbing(&action);
-            vd_pMedCapFail->RemoveHandler(reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap)));
-            SafeRelease(&vd_pMedCapFail);
-            vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(action, pOldAction, this)
-                HRESULT hr;
-                if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
-                DO_ACTION_SYNCHRONOUSLY(hr, action, GET_CURRENT_CONTEXT);
+            reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap))->remove_Failed(vd_cookie);
+            vd_cookie.value = 0;
+            vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, action, pOldAction, this)
+                HRESULT hr = S_OK;
+                if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
+                CREATE_TASK DEFINE_RET_TYPE(void)(action).wait();
                 RELEASE_WRL(vd_pMedCap)
                 if(vd_LockOut == RawDataLock) {
                     delete vd_pImGr;
@@ -2220,8 +2398,9 @@ void videoDevice::closeDevice()
             return;
         }
 #endif
+#endif
 
-        vd_pSource->Stop();
+        vd_pSource->Shutdown();
         SafeRelease(&vd_pSource);
         if(vd_LockOut == RawDataLock)
         {
@@ -2231,8 +2410,7 @@ void videoDevice::closeDevice()
         }
         vd_pImGrTh = NULL;
         vd_LockOut = OpenLock;
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"VIDEODEVICE %i: Device is stopped \n", vd_CurrentNumber);
+        DebugPrintOut(L"VIDEODEVICE %i: Device is stopped \n", vd_CurrentNumber);
     }
 }
 unsigned int videoDevice::getWidth()
@@ -2249,6 +2427,15 @@ unsigned int videoDevice::getHeight()
     else
         return 0;
 }
+
+unsigned int videoDevice::getFrameRate() const
+{
+    if(vd_IsSetuped)
+        return vd_FrameRate;
+    else
+        return 0;
+}
+
 IMFMediaSource *videoDevice::getMediaSource()
 {
     IMFMediaSource *out = NULL;
@@ -2261,17 +2448,26 @@ IMFMediaSource *videoDevice::getMediaSource()
 }
 int videoDevice::findType(unsigned int size, unsigned int frameRate)
 {
-    if(vd_CaptureFormats.size() == 0)
-        return 0;
-    FrameRateMap FRM = vd_CaptureFormats[size];
-    if(FRM.size() == 0)
-        return 0;
+    // For required frame size look for the suitable video format.
+    // If not found, get the format for the largest available frame size.
+    FrameRateMap FRM;
+    std::map<UINT64, FrameRateMap>::const_iterator fmt;
+    fmt = vd_CaptureFormats.find(size);
+    if( fmt != vd_CaptureFormats.end() )
+        FRM = fmt->second;
+    else
+        FRM = vd_CaptureFormats.rbegin()->second;
+
+    if( FRM.empty() )
+        return -1;
+
     UINT64 frameRateMax = 0;  SUBTYPEMap STMMax;
     if(frameRate == 0)
     {
         std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin();
         for(; f != FRM.end(); f++)
         {
+            // Looking for highest possible frame rate.
              if((*f).first >= frameRateMax)
              {
                  frameRateMax = (*f).first;
@@ -2284,22 +2480,26 @@ int videoDevice::findType(unsigned int size, unsigned int frameRate)
         std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin();
         for(; f != FRM.end(); f++)
         {
-             if((*f).first >= frameRateMax)
-             {
-                 if(frameRate > (*f).first)
-                 {
-                     frameRateMax = (*f).first;
-                     STMMax = (*f).second;
-                 }
-             }
+            // Looking for frame rate higher that recently found but not higher then demanded.
+            if( (*f).first >= frameRateMax && (*f).first <= frameRate )
+            {
+                frameRateMax = (*f).first;
+                STMMax = (*f).second;
+            }
         }
     }
-    if(STMMax.size() == 0)
-        return 0;
-    std::map<String, vectorNum>::iterator S = STMMax.begin();
-    vectorNum VN = (*S).second;
-    if(VN.size() == 0)
-        return 0;
+    // Get first (default) item from the list if no suitable frame rate found.
+    if( STMMax.empty() )
+        STMMax = FRM.begin()->second;
+
+    // Check if there are any format types on the list.
+    if( STMMax.empty() )
+        return -1;
+
+    vectorNum VN = STMMax.begin()->second;
+    if( VN.empty() )
+        return -1;
+
     return VN[0];
 }
 
@@ -2311,16 +2511,20 @@ void videoDevice::buildLibraryofTypes()
     int count = 0;
     for(; i != vd_CurrentFormats.end(); i++)
     {
-        size = (*i).MF_MT_FRAME_SIZE;
-        framerate = (*i).MF_MT_FRAME_RATE_NUMERATOR;
-        FrameRateMap FRM = vd_CaptureFormats[size];
-        SUBTYPEMap STM = FRM[framerate];
-        String subType((*i).pMF_MT_SUBTYPEName);
-        vectorNum VN = STM[subType];
-        VN.push_back(count);
-        STM[subType] = VN;
-        FRM[framerate] = STM;
-        vd_CaptureFormats[size] = FRM;
+        // Count only supported video formats.
+        if( (*i).MF_MT_SUBTYPE == MFVideoFormat_RGB24 )
+        {
+            size = (*i).MF_MT_FRAME_SIZE;
+            framerate = (*i).MF_MT_FRAME_RATE_NUMERATOR / (*i).MF_MT_FRAME_RATE_DENOMINATOR;
+            FrameRateMap FRM = vd_CaptureFormats[size];
+            SUBTYPEMap STM = FRM[framerate];
+            String subType((*i).pMF_MT_SUBTYPEName);
+            vectorNum VN = STM[subType];
+            VN.push_back(count);
+            STM[subType] = VN;
+            FRM[framerate] = STM;
+            vd_CaptureFormats[size] = FRM;
+        }
         count++;
     }
 }
@@ -2347,10 +2551,10 @@ long videoDevice::setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned
 
 long videoDevice::setDeviceFormat(IMFMediaSource *pSource, unsigned long  dwFormatIndex)
 {
-    ComPtr<IMFPresentationDescriptor> pPD = NULL;
-    ComPtr<IMFStreamDescriptor> pSD = NULL;
-    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
-    ComPtr<IMFMediaType> pType = NULL;
+    _ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    _ComPtr<IMFStreamDescriptor> pSD = NULL;
+    _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    _ComPtr<IMFMediaType> pType = NULL;
     HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
     if (FAILED(hr))
     {
@@ -2393,8 +2597,7 @@ RawImage * videoDevice::getRawImageOut()
             return vd_pImGrTh->getImageGrabber()->getRawImage();
     else
     {
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class does not exist  \n", vd_CurrentNumber);
+        DebugPrintOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class does not exist  \n", vd_CurrentNumber);
     }
     return NULL;
 }
@@ -2417,22 +2620,23 @@ bool videoDevice::isFrameNew()
                     delete vd_pImGr;
                     return false;
                 }
+#ifdef HAVE_CONCURRENCY
                 Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
                 MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
-                SAVE_CURRENT_CONTEXT(context);
-                vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(action, pOldAction, context, this)
-                    HRESULT hr;
-                    if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
-                    DO_ACTION_SYNCHRONOUSLY(hr, action, context);
+                DEFINE_TASK<void> _task = CREATE_TASK DEFINE_RET_TYPE(void)(action);
+                vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, _task, pOldAction, this)
+                    HRESULT hr = S_OK;
+                    if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
+                    _task.wait();
                 END_CREATE_ASYNC(hr));
+#endif
                 return true;
             }
 #endif
             HRESULT hr = ImageGrabberThread::CreateInstance(&vd_pImGrTh, vd_pSource, vd_CurrentNumber);
             if(FAILED(hr))
             {
-                DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-                DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class cannot be created.\n", vd_CurrentNumber);
+                DebugPrintOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class cannot be created.\n", vd_CurrentNumber);
                 return false;
             }
             vd_pImGrTh->setEmergencyStopEvent(vd_userData, vd_func);
@@ -2463,38 +2667,47 @@ bool videoDevice::isDeviceRawDataSource()
 
 bool videoDevice::setupDevice(unsigned int id)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if(!vd_IsSetuped)
     {
-        HRESULT hr = -1;
-        hr = initDevice();
+        HRESULT hr = initDevice();
         if(SUCCEEDED(hr))
         {
 #ifdef HAVE_WINRT
+#ifdef HAVE_CONCURRENCY
             Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
             MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
             SAVE_CURRENT_CONTEXT(context);
-            vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pOldAction, context, id, DPO, this)
+            vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, pOldAction, context, id, this)
                 HRESULT hr;
-                if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
+                if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
+#endif
 #endif
             vd_Width = vd_CurrentFormats[id].width;
             vd_Height = vd_CurrentFormats[id].height;
+            vd_FrameRate = vd_CurrentFormats[id].MF_MT_FRAME_RATE_NUMERATOR /
+                           vd_CurrentFormats[id].MF_MT_FRAME_RATE_DENOMINATOR;
 #ifdef HAVE_WINRT
+#ifdef HAVE_CONCURRENCY
             if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) {
-                MAKE_WRL_REF(_AsyncAction) pAction;
-                BEGIN_CALL_IN_CONTEXT(hr, context, id, &pAction, this)
-                END_CALL_IN_CONTEXT(setDeviceFormat(DEREF_AGILE_WRL_OBJ(vd_pMedCap), (DWORD) id, &pAction))
-                if (SUCCEEDED(hr)) DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
+                DEFINE_TASK<void> _task;
+                BEGIN_CALL_IN_CONTEXT(hr, context, id, &_task, this)
+                    MAKE_WRL_REF(_AsyncAction) pAction;
+                    HRESULT hr = setDeviceFormat(DEREF_AGILE_WRL_OBJ(vd_pMedCap), (DWORD) id, &pAction);
+                    if (SUCCEEDED(hr)) _task = CREATE_TASK DEFINE_RET_TYPE(void)(pAction);
+                END_CALL_IN_CONTEXT(hr)
+                if (SUCCEEDED(hr)) _task.wait();
             } else
 #endif
+#endif
             hr = setDeviceFormat(vd_pSource, (DWORD) id);
             vd_IsSetuped = (SUCCEEDED(hr));
             if(vd_IsSetuped)
-                DPO->printOut(L"\n\nVIDEODEVICE %i: Device is setuped \n", vd_CurrentNumber);
+                DebugPrintOut(L"\n\nVIDEODEVICE %i: Device is setuped \n", vd_CurrentNumber);
             vd_PrevParametrs = getParametrs();
 #ifdef HAVE_WINRT
+#ifdef HAVE_CONCURRENCY
             END_CREATE_ASYNC(hr));
+#endif
             return true;
 #else
             return vd_IsSetuped;
@@ -2502,13 +2715,13 @@ bool videoDevice::setupDevice(unsigned int id)
         }
         else
         {
-            DPO->printOut(L"VIDEODEVICE %i: Interface IMFMediaSource cannot be got \n", vd_CurrentNumber);
+            DebugPrintOut(L"VIDEODEVICE %i: Interface IMFMediaSource cannot be got \n", vd_CurrentNumber);
             return false;
         }
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE %i: Device is setuped already \n", vd_CurrentNumber);
+        DebugPrintOut(L"VIDEODEVICE %i: Device is setuped already \n", vd_CurrentNumber);
         return false;
     }
 }
@@ -2516,6 +2729,9 @@ bool videoDevice::setupDevice(unsigned int id)
 bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate)
 {
     unsigned int id = findType(w * h, idealFramerate);
+    if( id < 0 )
+        return false;
+
     return setupDevice(id);
 }
 
@@ -2554,7 +2770,7 @@ HRESULT videoDevice::enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource
         MAKE_WRL_OBJ(_MediaEncodingProperties) pMedEncProps;
         WRL_METHOD(pVector, GetAt, pMedEncProps, hr, i)
         if (FAILED(hr)) return hr;
-        ComPtr<IMFMediaType> pType = NULL;
+        _ComPtr<IMFMediaType> pType = NULL;
         hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType);
         if (FAILED(hr)) return hr;
         MediaType MT = FormatReader::Read(pType.Get());
@@ -2566,10 +2782,10 @@ HRESULT videoDevice::enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource
 
 HRESULT videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
 {
-    ComPtr<IMFPresentationDescriptor> pPD = NULL;
-    ComPtr<IMFStreamDescriptor> pSD = NULL;
-    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
-    ComPtr<IMFMediaType> pType = NULL;
+    _ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    _ComPtr<IMFStreamDescriptor> pSD = NULL;
+    _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    _ComPtr<IMFMediaType> pType = NULL;
     HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
     if (FAILED(hr))
     {
@@ -2649,11 +2865,12 @@ long videoDevices::initDevices(_DeviceClass devClass)
     MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction;
     WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass)
     if (SUCCEEDED(hr)) {
+#ifdef HAVE_CONCURRENCY
            SAVE_CURRENT_CONTEXT(context);
-           vds_enumTask = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, context, this)
-            HRESULT hr;
-            MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector;
-            DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, pAction, GET_CURRENT_CONTEXT, pVector, _VectorView, _DeviceInformation, _DeviceInformationCollection);
+           vds_enumTask = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, pAction, context, this)
+            HRESULT hr = S_OK;
+            MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector =
+                CREATE_TASK DEFINE_RET_TYPE(MAKE_WRL_REF(_VectorView<MAKE_WRL_REF(_DeviceInformation)>))(pAction).get();
             if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr)
             if (SUCCEEDED(hr) && count > 0) {
                 for (UINT32 i = 0; i < count; i++) {
@@ -2663,22 +2880,22 @@ long videoDevices::initDevices(_DeviceClass devClass)
                     if (SUCCEEDED(hr)) {
                         BEGIN_CALL_IN_CONTEXT(hr, context, vd, pDevice, i)
                             vd->readInfoOfDevice(DEREF_WRL_OBJ(pDevice), i);
-                        END_CALL_IN_CONTEXT(S_OK)
+                        END_CALL_IN_CONTEXT_BASE
                         vds_Devices.push_back(vd);
                     }
                 }
             }
         END_CREATE_ASYNC(hr));
+#endif
     }
     return hr;
 }
 #else
 long videoDevices::initDevices(IMFAttributes *pAttributes)
 {
-    HRESULT hr = S_OK;
     clearDevices();
     IMFActivate **ppDevices = NULL;
-    hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
+    HRESULT hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
     if (SUCCEEDED(hr))
     {
         if(count > 0)
@@ -2693,12 +2910,11 @@ long videoDevices::initDevices(IMFAttributes *pAttributes)
             SafeRelease(ppDevices);
         }
         else
-            hr = -1;
+            hr = E_INVALIDARG;
     }
     else
     {
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"VIDEODEVICES: The instances of the videoDevice class cannot be created\n");
+        DebugPrintOut(L"VIDEODEVICES: The instances of the videoDevice class cannot be created\n");
     }
     return hr;
 }
@@ -2768,56 +2984,50 @@ void MediaType::Clear()
 
 videoInput::videoInput(void): accessToDevices(false)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->printOut(L"\n***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****\n\n");
+    DebugPrintOut(L"\n***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****\n\n");
     updateListOfDevices();
     if(!accessToDevices)
-        DPO->printOut(L"INITIALIZATION: There is not any suitable video device\n");
+        DebugPrintOut(L"INITIALIZATION: There is not any suitable video device\n");
 }
 
 void videoInput::updateListOfDevices()
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     Media_Foundation *MF = &Media_Foundation::getInstance();
     accessToDevices = MF->buildListOfDevices();
     if(!accessToDevices)
-        DPO->printOut(L"UPDATING: There is not any suitable video device\n");
+        DebugPrintOut(L"UPDATING: There is not any suitable video device\n");
 }
 
 videoInput::~videoInput(void)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->printOut(L"\n***** CLOSE VIDEOINPUT LIBRARY - 2013 *****\n\n");
+    DebugPrintOut(L"\n***** CLOSE VIDEOINPUT LIBRARY - 2013 *****\n\n");
 }
 
 IMFMediaSource *videoInput::getMediaSource(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if(accessToDevices)
     {
-        videoDevices *VDS = &videoDevices::getInstance();
-        videoDevice * VD = VDS->getDevice(deviceID);
+        videoDevice * VD = videoDevices::getInstance().getDevice(deviceID);
         if(VD)
         {
             IMFMediaSource *out = VD->getMediaSource();
             if(!out)
-                DPO->printOut(L"VideoDevice %i: There is not any suitable IMFMediaSource interface\n", deviceID);
+                DebugPrintOut(L"VideoDevice %i: There is not any suitable IMFMediaSource interface\n", deviceID);
             return out;
         }
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return NULL;
 }
 
 bool videoInput::setupDevice(int deviceID, unsigned int id)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0 )
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return false;
     }
     if(accessToDevices)
@@ -2828,23 +3038,22 @@ bool videoInput::setupDevice(int deviceID, unsigned int id)
         {
             bool out = VD->setupDevice(id);
             if(!out)
-                DPO->printOut(L"VIDEODEVICE %i: This device cannot be started\n", deviceID);
+                DebugPrintOut(L"VIDEODEVICE %i: This device cannot be started\n", deviceID);
             return out;
         }
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return false;
 }
 
 bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0 )
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return false;
     }
     if(accessToDevices)
@@ -2855,23 +3064,22 @@ bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsig
         {
             bool out = VD->setupDevice(w, h, idealFramerate);
             if(!out)
-                DPO->printOut(L"VIDEODEVICE %i: this device cannot be started\n", deviceID);
+                DebugPrintOut(L"VIDEODEVICE %i: this device cannot be started\n", deviceID);
             return out;
         }
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n", deviceID);
     }
     return false;
 }
 
 MediaType videoInput::getFormat(int deviceID, unsigned int id)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return MediaType();
     }
     if(accessToDevices)
@@ -2883,17 +3091,16 @@ MediaType videoInput::getFormat(int deviceID, unsigned int id)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return MediaType();
 }
 
 bool videoInput::isDeviceSetup(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return false;
     }
     if(accessToDevices)
@@ -2905,17 +3112,16 @@ bool videoInput::isDeviceSetup(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return false;
 }
 
 bool videoInput::isDeviceMediaSource(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return false;
     }
     if(accessToDevices)
@@ -2927,17 +3133,16 @@ bool videoInput::isDeviceMediaSource(int deviceID)
     }
     else
     {
-        DPO->printOut(L"Device(s): There is not any suitable video device\n");
+        DebugPrintOut(L"Device(s): There is not any suitable video device\n");
     }
     return false;
 }
 
 bool videoInput::isDeviceRawDataSource(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return false;
     }
     if(accessToDevices)
@@ -2952,17 +3157,16 @@ bool videoInput::isDeviceRawDataSource(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return false;
 }
 
 bool videoInput::isFrameNew(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return false;
     }
     if(accessToDevices)
@@ -2981,7 +3185,7 @@ bool videoInput::isFrameNew(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return false;
 }
@@ -2989,10 +3193,9 @@ bool videoInput::isFrameNew(int deviceID)
 #ifdef HAVE_WINRT
 void videoInput::waitForDevice(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return;
     }
     if(accessToDevices)
@@ -3011,7 +3214,7 @@ void videoInput::waitForDevice(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return;
 }
@@ -3019,10 +3222,9 @@ void videoInput::waitForDevice(int deviceID)
 
 unsigned int videoInput::getCountFormats(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return 0;
     }
     if(accessToDevices)
@@ -3034,7 +3236,7 @@ unsigned int videoInput::getCountFormats(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return 0;
 }
@@ -3048,10 +3250,9 @@ void videoInput::closeAllDevices()
 
 void videoInput::setParametrs(int deviceID, CamParametrs parametrs)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return;
     }
     if(accessToDevices)
@@ -3063,17 +3264,16 @@ void videoInput::setParametrs(int deviceID, CamParametrs parametrs)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
 }
 
 CamParametrs videoInput::getParametrs(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     CamParametrs out;
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return out;
     }
     if(accessToDevices)
@@ -3085,17 +3285,16 @@ CamParametrs videoInput::getParametrs(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return out;
 }
 
 void videoInput::closeDevice(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return;
     }
     if(accessToDevices)
@@ -3107,16 +3306,15 @@ void videoInput::closeDevice(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
 }
 
 unsigned int videoInput::getWidth(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return 0;
     }
     if(accessToDevices)
@@ -3128,17 +3326,16 @@ unsigned int videoInput::getWidth(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return 0;
 }
 
 unsigned int videoInput::getHeight(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return 0;
     }
     if(accessToDevices)
@@ -3150,17 +3347,36 @@ unsigned int videoInput::getHeight(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+    }
+    return 0;
+}
+
+unsigned int videoInput::getFrameRate(int deviceID) const
+{
+    if (deviceID < 0)
+    {
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        return 0;
+    }
+    if(accessToDevices)
+    {
+        videoDevice * VD = videoDevices::getInstance().getDevice(deviceID);
+        if(VD)
+            return VD->getFrameRate();
+    }
+    else
+    {
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return 0;
 }
 
 wchar_t *videoInput::getNameVideoDevice(int deviceID)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return NULL;
     }
     if(accessToDevices)
@@ -3172,14 +3388,13 @@ wchar_t *videoInput::getNameVideoDevice(int deviceID)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return L"Empty";
 }
 
 unsigned int videoInput::listDevices(bool silent)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     int out = 0;
     if(accessToDevices)
     {
@@ -3188,18 +3403,17 @@ unsigned int videoInput::listDevices(bool silent)
         VDS->waitInit();
 #endif
         out = VDS->getCount();
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        if(!silent)DPO->printOut(L"\nVIDEOINPUT SPY MODE!\n\n");
-        if(!silent)DPO->printOut(L"SETUP: Looking For Capture Devices\n");
+        if(!silent) DebugPrintOut(L"\nVIDEOINPUT SPY MODE!\n\n");
+        if(!silent) DebugPrintOut(L"SETUP: Looking For Capture Devices\n");
         for(int i = 0; i < out; i++)
         {
-            if(!silent)DPO->printOut(L"SETUP: %i) %s \n",i, getNameVideoDevice(i));
+            if(!silent) DebugPrintOut(L"SETUP: %i) %s \n",i, getNameVideoDevice(i));
         }
-        if(!silent)DPO->printOut(L"SETUP: %i Device(s) found\n\n", out);
+        if(!silent) DebugPrintOut(L"SETUP: %i Device(s) found\n\n", out);
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return out;
 }
@@ -3215,18 +3429,19 @@ bool videoInput::isDevicesAcceable()
     return accessToDevices;
 }
 
+#ifdef _DEBUG
 void videoInput::setVerbose(bool state)
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->setVerbose(state);
+    DPO *dpo = &DPO::getInstance();
+    dpo->setVerbose(state);
 }
+#endif
 
 void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *))
 {
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return;
     }
     if(accessToDevices)
@@ -3241,18 +3456,16 @@ void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
 }
 
 bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRedAndBlue, bool flipImage)
 {
     bool success = false;
-    unsigned int bytes = 3;
-    DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     if (deviceID < 0)
     {
-        DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
+        DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
         return success;
     }
     if(accessToDevices)
@@ -3260,14 +3473,14 @@ bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRed
         bool isRaw = isDeviceRawDataSource(deviceID);
         if(isRaw)
         {
-            videoDevices *VDS = &videoDevices::getInstance();
-            DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-            RawImage *RIOut = VDS->getDevice(deviceID)->getRawImageOut();
+            videoDevice *VD = videoDevices::getInstance().getDevice(deviceID);
+            RawImage *RIOut = VD->getRawImageOut();
             if(RIOut)
             {
-                unsigned int height = VDS->getDevice(deviceID)->getHeight();
-                unsigned int width  = VDS->getDevice(deviceID)->getWidth();
-                unsigned int size = bytes * width * height;
+                const unsigned int bytes = 3;
+                const unsigned int height = VD->getHeight();
+                const unsigned int width  = VD->getWidth();
+                const unsigned int size = bytes * width * height;
                 if(size == RIOut->getSize())
                 {
                     processPixels(RIOut->getpPixels(), dstBuffer, width, height, bytes, flipRedAndBlue, flipImage);
@@ -3275,22 +3488,22 @@ bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRed
                 }
                 else
                 {
-                    DPO->printOut(L"ERROR: GetPixels() - bufferSizes do not match!\n");
+                    DebugPrintOut(L"ERROR: GetPixels() - bufferSizes do not match!\n");
                 }
             }
             else
             {
-                DPO->printOut(L"ERROR: GetPixels() - Unable to grab frame for device %i\n", deviceID);
+                DebugPrintOut(L"ERROR: GetPixels() - Unable to grab frame for device %i\n", deviceID);
             }
         }
         else
         {
-            DPO->printOut(L"ERROR: GetPixels() - Not raw data source device %i\n", deviceID);
+            DebugPrintOut(L"ERROR: GetPixels() - Not raw data source device %i\n", deviceID);
         }
     }
     else
     {
-        DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
+        DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
     return success;
 }
@@ -3377,17 +3590,21 @@ protected:
     IplImage* frame;
     videoInput VI;
 #ifdef HAVE_WINRT
+#ifdef HAVE_CONCURRENCY
     DEFINE_TASK<bool> openTask;
     Concurrency::critical_section lock;
 #endif
+#endif
 };
 
+#ifdef _DEBUG
 struct SuppressVideoInputMessages
 {
     SuppressVideoInputMessages() { videoInput::setVerbose(true); }
 };
 
 static SuppressVideoInputMessages do_it;
+#endif
 
 CvCaptureCAM_MSMF::CvCaptureCAM_MSMF():
     index(-1),
@@ -3421,8 +3638,10 @@ void CvCaptureCAM_MSMF::close()
 bool CvCaptureCAM_MSMF::open( int _index )
 {
 #ifdef HAVE_WINRT
+#ifdef HAVE_CONCURRENCY
     SAVE_CURRENT_CONTEXT(context);
-    auto func = [_index, context, this]() -> bool {
+    auto func = [_index, context, this](DEFINE_RET_VAL(bool)) -> DEFINE_RET_FORMAL(bool) {
+#endif
 #endif
     int try_index = _index;
     int devices = 0;
@@ -3433,15 +3652,19 @@ bool CvCaptureCAM_MSMF::open( int _index )
     try_index = try_index < 0 ? 0 : (try_index > devices-1 ? devices-1 : try_index);
 #ifdef HAVE_WINRT
     HRESULT hr;
+#ifdef HAVE_CONCURRENCY
     BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index)
 #endif
-    VI.setupDevice(try_index);
+#endif
+    VI.setupDevice(try_index, 0, 0, 0); // With maximum frame size.
 #ifdef HAVE_WINRT
-    END_CALL_IN_CONTEXT(S_OK)
+#ifdef HAVE_CONCURRENCY
+    END_CALL_IN_CONTEXT_BASE
     VI.waitForDevice(try_index);
     BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index)
     HRESULT hr = S_OK;
 #endif
+#endif
     if( !VI.isFrameNew(try_index) )
 #ifdef HAVE_WINRT
         hr = E_FAIL;
@@ -3450,12 +3673,14 @@ bool CvCaptureCAM_MSMF::open( int _index )
 #endif
     index = try_index;
 #ifdef HAVE_WINRT
-    END_CALL_IN_CONTEXT(hr);
-    return true;
+#ifdef HAVE_CONCURRENCY
+    END_CALL_IN_CONTEXT_BASE
+    RET_VAL(true)
     };
     Concurrency::critical_section::scoped_lock _LockHolder(lock);
     CREATE_OR_CONTINUE_TASK(openTask, bool, func)
 #endif
+#endif
     return true;
 }
 
@@ -3468,11 +3693,12 @@ bool CvCaptureCAM_MSMF::grabFrame()
 
 IplImage* CvCaptureCAM_MSMF::retrieveFrame(int)
 {
-    if( !frame || (int)VI.getWidth(index) != frame->width || (int)VI.getHeight(index) != frame->height )
+    const int w = (int)VI.getWidth(index);
+    const int h = (int)VI.getHeight(index);
+    if( !frame || w != frame->width || h != frame->height )
     {
         if (frame)
             cvReleaseImage( &frame );
-        unsigned int w = VI.getWidth(index), h = VI.getHeight(index);
         frame = cvCreateImage( cvSize(w,h), 8, 3 );
     }
     VI.getPixels( index, (uchar*)frame->imageData, false, true );
@@ -3488,33 +3714,47 @@ double CvCaptureCAM_MSMF::getProperty( int property_id )
         return VI.getWidth(index);
     case CV_CAP_PROP_FRAME_HEIGHT:
         return VI.getHeight(index);
+    case CV_CAP_PROP_FPS:
+        return VI.getFrameRate(index);
+    default:
+        break;
     }
-    return -1;
+    return 0;
 }
 bool CvCaptureCAM_MSMF::setProperty( int property_id, double value )
 {
     // image capture properties
+    unsigned int fps = 0;
     bool handled = false;
     switch( property_id )
     {
     case CV_CAP_PROP_FRAME_WIDTH:
         width = cvRound(value);
+        fps = VI.getFrameRate(index);
         handled = true;
         break;
     case CV_CAP_PROP_FRAME_HEIGHT:
         height = cvRound(value);
+        fps = VI.getFrameRate(index);
         handled = true;
         break;
+    case CV_CAP_PROP_FPS:
+        width = (int)VI.getHeight(index);
+        height = (int)VI.getWidth(index);
+        fps = cvRound(value);
+        break;
     }
 
     if ( handled ) {
         if( width > 0 && height > 0 )
         {
-            if( width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index)  && VI.isDeviceSetup(index))//|| fourcc != VI.getFourcc(index) )
+            if( (width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index) || fps != VI.getFrameRate(index))
+                && VI.isDeviceSetup(index))//|| fourcc != VI.getFourcc(index) )
             {
                 VI.closeDevice(index);
-                VI.setupDevice(index, width, height);
+                VI.setupDevice(index, width, height, fps);
             }
+            width = height = -1;
             return VI.isDeviceSetup(index);
         }
         return true;
@@ -3573,14 +3813,12 @@ bool CvCaptureFile_MSMF::open(const char* filename)
     wchar_t* unicodeFileName = new wchar_t[strlen(filename)+1];
     MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename)+1);
 
-    HRESULT hr = S_OK;
-
     MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
 
-    ComPtr<IMFSourceResolver> pSourceResolver = NULL;
+    _ComPtr<IMFSourceResolver> pSourceResolver = NULL;
     IUnknown* pUnkSource = NULL;
 
-    hr = MFCreateSourceResolver(pSourceResolver.GetAddressOf());
+    HRESULT hr = MFCreateSourceResolver(pSourceResolver.GetAddressOf());
 
     if (SUCCEEDED(hr))
     {
@@ -3714,10 +3952,10 @@ IplImage* CvCaptureFile_MSMF::retrieveFrame(int)
 
 HRESULT CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource)
 {
-    ComPtr<IMFPresentationDescriptor> pPD = NULL;
-    ComPtr<IMFStreamDescriptor> pSD = NULL;
-    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
-    ComPtr<IMFMediaType> pType = NULL;
+    _ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    _ComPtr<IMFStreamDescriptor> pSD = NULL;
+    _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    _ComPtr<IMFMediaType> pType = NULL;
     HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
     if (FAILED(hr))
     {
@@ -3834,7 +4072,7 @@ private:
     GUID   inputFormat;
 
     DWORD  streamIndex;
-    ComPtr<IMFSinkWriter> sinkWriter;
+    _ComPtr<IMFSinkWriter> sinkWriter;
 
     bool   initiated;
 
@@ -3874,8 +4112,10 @@ const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc)
             return MFVideoFormat_DVSD; break;
         case CV_FOURCC_MACRO('d', 'v', 's', 'l'):
                 return MFVideoFormat_DVSL; break;
-        case CV_FOURCC_MACRO('H', '2', '6', '3'):
+#if (WINVER >= _WIN32_WINNT_WIN8)
+        case CV_FOURCC_MACRO('H', '2', '6', '3'):   // Available only for Win 8 target.
                 return MFVideoFormat_H263; break;
+#endif
         case CV_FOURCC_MACRO('H', '2', '6', '4'):
                 return MFVideoFormat_H264; break;
         case CV_FOURCC_MACRO('M', '4', 'S', '2'):
@@ -3985,10 +4225,10 @@ bool CvVideoWriter_MSMF::writeFrame(const IplImage* img)
 
 HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename)
 {
-    ComPtr<IMFAttributes> spAttr;
-    ComPtr<IMFMediaType>  mediaTypeOut;
-    ComPtr<IMFMediaType>  mediaTypeIn;
-    ComPtr<IMFByteStream> spByteStream;
+    _ComPtr<IMFAttributes> spAttr;
+    _ComPtr<IMFMediaType>  mediaTypeOut;
+    _ComPtr<IMFMediaType>  mediaTypeIn;
+    _ComPtr<IMFByteStream> spByteStream;
 
     MFCreateAttributes(&spAttr, 10);
     spAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
@@ -4085,8 +4325,8 @@ HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename)
 
 HRESULT CvVideoWriter_MSMF::WriteFrame(DWORD *videoFrameBuffer, const LONGLONG& Start, const LONGLONG& Duration)
 {
-    ComPtr<IMFSample> sample;
-    ComPtr<IMFMediaBuffer> buffer;
+    _ComPtr<IMFSample> sample;
+    _ComPtr<IMFMediaBuffer> buffer;
 
     const LONG cbWidth = 4 * videoWidth;
     const DWORD cbBuffer = cbWidth * videoHeight;
index c212ca9..bf3741b 100644 (file)
@@ -1,6 +1,206 @@
 #ifdef HAVE_WINRT
 #define ICustomStreamSink StreamSink
-#include "ppltasks_winrt.h"
+#ifndef __cplusplus_winrt
+
+#define __is_winrt_array(type) (type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt8Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int16Array ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt16Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int32Array ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt32Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int64Array ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt64Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_SingleArray ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_DoubleArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_Char16Array ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_BooleanArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_StringArray ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_InspectableArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_DateTimeArray ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_TimeSpanArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_GuidArray ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_PointArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_SizeArray ||\
+    type == ABI::Windows::Foundation::PropertyType::PropertyType_RectArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_OtherTypeArray)
+
+template<typename _Type, bool bUnknown = std::is_base_of<IUnknown, _Type>::value>
+struct winrt_type
+{
+};
+template<typename _Type>
+struct winrt_type<_Type, true>
+{
+    static IUnknown* create(_Type* _ObjInCtx) {
+        return reinterpret_cast<IUnknown*>(_ObjInCtx);
+    }
+    static IID getuuid() { return __uuidof(_Type); }
+    static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherType;
+};
+template <typename _Type>
+struct winrt_type<_Type, false>
+{
+    static IUnknown* create(_Type* _ObjInCtx) {
+        Microsoft::WRL::ComPtr<IInspectable> _PObj;
+        Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
+        HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
+        if (FAILED(hr)) return nullptr;
+        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
+        if (SUCCEEDED(hr))
+            hr = objFactory.As(&spPropVal);
+        if (SUCCEEDED(hr)) {
+            hr = winrt_type<_Type>::create(spPropVal.Get(), _ObjInCtx, _PObj.GetAddressOf());
+            if (SUCCEEDED(hr))
+                return reinterpret_cast<IUnknown*>(_PObj.Detach());
+        }
+        return nullptr;
+    }
+    static IID getuuid() { return __uuidof(ABI::Windows::Foundation::IPropertyValue); }
+    static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherType;
+};
+
+template<>
+struct winrt_type<void>
+{
+    static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, void* _ObjInCtx, IInspectable** ppInsp) {
+        (void)_ObjInCtx;
+        return spPropVal->CreateEmpty(ppInsp);
+    }
+    static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
+};
+#define MAKE_TYPE(Type, Name) template<>\
+struct winrt_type<Type>\
+{\
+    static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, Type* _ObjInCtx, IInspectable** ppInsp) {\
+    return spPropVal->Create##Name(*_ObjInCtx, ppInsp);\
+}\
+    static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_##Name;\
+};
+
+template<typename _Type>
+struct winrt_array_type
+{
+    static IUnknown* create(_Type* _ObjInCtx, size_t N) {
+        Microsoft::WRL::ComPtr<IInspectable> _PObj;
+        Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
+        HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
+        if (FAILED(hr)) return nullptr;
+        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
+        if (SUCCEEDED(hr))
+            hr = objFactory.As(&spPropVal);
+        if (SUCCEEDED(hr)) {
+            hr = winrt_array_type<_Type>::create(spPropVal.Get(), N, _ObjInCtx, _PObj.GetAddressOf());
+            if (SUCCEEDED(hr))
+                return reinterpret_cast<IUnknown*>(_PObj.Detach());
+        }
+        return nullptr;
+    }
+    static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherTypeArray;
+};
+template<int>
+struct winrt_prop_type {};
+
+template <>
+struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_Empty> {
+    typedef void _Type;
+};
+
+template <>
+struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_OtherType> {
+    typedef void _Type;
+};
+
+template <>
+struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_OtherTypeArray> {
+    typedef void _Type;
+};
+
+#define MAKE_PROP(Prop, Type) template <>\
+struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_##Prop> {\
+    typedef Type _Type;\
+};
+
+#define MAKE_ARRAY_TYPE(Type, Name) MAKE_PROP(Name, Type)\
+    MAKE_PROP(Name##Array, Type*)\
+    MAKE_TYPE(Type, Name)\
+    template<>\
+struct winrt_array_type<Type*>\
+{\
+    static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, Type** _ObjInCtx, IInspectable** ppInsp) {\
+    return spPropVal->Create##Name##Array(__valueSize, *_ObjInCtx, ppInsp);\
+}\
+    static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_##Name##Array;\
+    static std::vector<Type> PropertyValueToVector(ABI::Windows::Foundation::IPropertyValue* propValue)\
+{\
+    UINT32 uLen = 0;\
+    Type* pArray = nullptr;\
+    propValue->Get##Name##Array(&uLen, &pArray);\
+    return std::vector<Type>(pArray, pArray + uLen);\
+}\
+};
+MAKE_ARRAY_TYPE(BYTE, UInt8)
+MAKE_ARRAY_TYPE(INT16, Int16)
+MAKE_ARRAY_TYPE(UINT16, UInt16)
+MAKE_ARRAY_TYPE(INT32, Int32)
+MAKE_ARRAY_TYPE(UINT32, UInt32)
+MAKE_ARRAY_TYPE(INT64, Int64)
+MAKE_ARRAY_TYPE(UINT64, UInt64)
+MAKE_ARRAY_TYPE(FLOAT, Single)
+MAKE_ARRAY_TYPE(DOUBLE, Double)
+MAKE_ARRAY_TYPE(WCHAR, Char16)
+//MAKE_ARRAY_TYPE(boolean, Boolean) //conflict with identical type in C++ of BYTE/UInt8
+MAKE_ARRAY_TYPE(HSTRING, String)
+MAKE_ARRAY_TYPE(IInspectable*, Inspectable)
+MAKE_ARRAY_TYPE(GUID, Guid)
+MAKE_ARRAY_TYPE(ABI::Windows::Foundation::DateTime, DateTime)
+MAKE_ARRAY_TYPE(ABI::Windows::Foundation::TimeSpan, TimeSpan)
+MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Point, Point)
+MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Size, Size)
+MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Rect, Rect)
+
+template < typename T >
+struct DerefHelper
+{
+    typedef T DerefType;
+};
+
+template < typename T >
+struct DerefHelper<T*>
+{
+    typedef T DerefType;
+};
+
+#define __is_valid_winrt_type(_Type) (std::is_void<_Type>::value || \
+    std::is_same<_Type, BYTE>::value || \
+    std::is_same<_Type, INT16>::value || \
+    std::is_same<_Type, UINT16>::value || \
+    std::is_same<_Type, INT32>::value || \
+    std::is_same<_Type, UINT32>::value || \
+    std::is_same<_Type, INT64>::value || \
+    std::is_same<_Type, UINT64>::value || \
+    std::is_same<_Type, FLOAT>::value || \
+    std::is_same<_Type, DOUBLE>::value || \
+    std::is_same<_Type, WCHAR>::value || \
+    std::is_same<_Type, boolean>::value || \
+    std::is_same<_Type, HSTRING>::value || \
+    std::is_same<_Type, IInspectable *>::value || \
+    std::is_base_of<Microsoft::WRL::Details::RuntimeClassBase, _Type>::value || \
+    std::is_base_of<IInspectable, typename DerefHelper<_Type>::DerefType>::value || \
+    std::is_same<_Type, GUID>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::DateTime>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::TimeSpan>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::Point>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::Size>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::Rect>::value || \
+    std::is_same<_Type, BYTE*>::value || \
+    std::is_same<_Type, INT16*>::value || \
+    std::is_same<_Type, UINT16*>::value || \
+    std::is_same<_Type, INT32*>::value || \
+    std::is_same<_Type, UINT32*>::value || \
+    std::is_same<_Type, INT64*>::value || \
+    std::is_same<_Type, UINT64*>::value || \
+    std::is_same<_Type, FLOAT*>::value || \
+    std::is_same<_Type, DOUBLE*>::value || \
+    std::is_same<_Type, WCHAR*>::value || \
+    std::is_same<_Type, boolean*>::value || \
+    std::is_same<_Type, HSTRING*>::value || \
+    std::is_same<_Type, IInspectable **>::value || \
+    std::is_same<_Type, GUID*>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::DateTime*>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::TimeSpan*>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::Point*>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::Size*>::value || \
+    std::is_same<_Type, ABI::Windows::Foundation::Rect*>::value)
+#endif
 #else
 EXTERN_C const IID IID_ICustomStreamSink;
 
@@ -179,11 +379,32 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP
 #ifdef HAVE_WINRT
 
 #ifdef __cplusplus_winrt
+#define _ContextCallback Concurrency::details::_ContextCallback
+#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = S_OK;\
+    var._CallInContext([__VA_ARGS__]() {
+#define END_CALL_IN_CONTEXT(hr) if (FAILED(hr)) throw Platform::Exception::CreateException(hr);\
+});
+#define END_CALL_IN_CONTEXT_BASE });
+#else
+#define _ContextCallback Concurrency_winrt::details::_ContextCallback
+#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = var._CallInContext([__VA_ARGS__]() -> HRESULT {
+#define END_CALL_IN_CONTEXT(hr) return hr;\
+});
+#define END_CALL_IN_CONTEXT_BASE return S_OK;\
+});
+#endif
+#define GET_CURRENT_CONTEXT _ContextCallback::_CaptureCurrent()
+#define SAVE_CURRENT_CONTEXT(var) _ContextCallback var = GET_CURRENT_CONTEXT
+
+#define COMMA ,
+
+#ifdef __cplusplus_winrt
 #define _Object Platform::Object^
 #define _ObjectObj Platform::Object^
 #define _String Platform::String^
 #define _StringObj Platform::String^
 #define _StringReference ref new Platform::String
+#define _StringReferenceObj Platform::String^
 #define _DeviceInformationCollection Windows::Devices::Enumeration::DeviceInformationCollection
 #define _MediaCapture Windows::Media::Capture::MediaCapture
 #define _MediaCaptureVideoPreview Windows::Media::Capture::MediaCapture
@@ -193,6 +414,7 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP
 #define _MediaEncodingProperties Windows::Media::MediaProperties::IMediaEncodingProperties
 #define _VideoEncodingProperties Windows::Media::MediaProperties::VideoEncodingProperties
 #define _MediaStreamType Windows::Media::Capture::MediaStreamType
+#define _AsyncInfo Windows::Foundation::IAsyncInfo
 #define _AsyncAction Windows::Foundation::IAsyncAction
 #define _AsyncOperation Windows::Foundation::IAsyncOperation
 #define _DeviceClass Windows::Devices::Enumeration::DeviceClass
@@ -209,29 +431,37 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP
 #define _InitializeWithSettingsAsync InitializeAsync
 #define _FindAllAsyncDeviceClass FindAllAsync
 #define _MediaExtension Windows::Media::IMediaExtension
-#define _ContextCallback Concurrency::details::_ContextCallback
-#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = S_OK;\
-var._CallInContext([__VA_ARGS__]() {
-#define END_CALL_IN_CONTEXT(hr) if (FAILED(hr)) throw Platform::Exception::CreateException(hr);\
-});
-#define DO_ACTION_SYNCHRONOUSLY(hr, action, ctxt) hr = S_OK;\
-CCompletionHandler::PerformActionSynchronously(reinterpret_cast<Windows::Foundation::IAsyncAction^>(action), ctxt)
-#define DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, action, ctxt, pResult, vectortype, elementtype, _type) hr = S_OK;\
-pResult = CCompletionHandler::PerformSynchronously<_type^>(reinterpret_cast<Windows::Foundation::IAsyncOperation<_type^>^>(action), ctxt)
-#define BEGIN_CREATE_ASYNC(...) reinterpret_cast<ABI::Windows::Foundation::IAsyncAction*>(Concurrency::create_async([__VA_ARGS__]() {
+#define BEGIN_CREATE_ASYNC(type, ...) (Concurrency::create_async([__VA_ARGS__]() {
 #define END_CREATE_ASYNC(hr) if (FAILED(hr)) throw Platform::Exception::CreateException(hr);\
 }))
 #define DEFINE_TASK Concurrency::task
 #define CREATE_TASK Concurrency::create_task
 #define CREATE_OR_CONTINUE_TASK(_task, rettype, func) _task = (_task == Concurrency::task<rettype>()) ? Concurrency::create_task(func) : _task.then([func](rettype) -> rettype { return func(); });
+#define DEFINE_RET_VAL(x)
+#define DEFINE_RET_TYPE(x)
+#define DEFINE_RET_FORMAL(x) x
+#define RET_VAL(x) return x;
+#define RET_VAL_BASE
+#define MAKE_STRING(str) str
+#define GET_STL_STRING(str) std::wstring(str->Data())
+#define GET_STL_STRING_RAW(str) std::wstring(str->Data())
 #define MAKE_WRL_OBJ(x) x^
 #define MAKE_WRL_REF(x) x^
+#define MAKE_OBJ_REF(x) x^
 #define MAKE_WRL_AGILE_REF(x) Platform::Agile<x^>
+#define MAKE_PROPERTY_BACKING(Type, PropName) property Type PropName;
+#define MAKE_PROPERTY(Type, PropName, PropValue)
+#define MAKE_PROPERTY_STRING(Type, PropName, PropValue)
+#define MAKE_READONLY_PROPERTY(Type, PropName, PropValue) property Type PropName\
+{\
+    Type get() { return PropValue; }\
+}
+#define THROW_INVALID_ARG throw ref new Platform::InvalidArgumentException();
 #define RELEASE_AGILE_WRL(x) x = nullptr;
 #define RELEASE_WRL(x) x = nullptr;
 #define GET_WRL_OBJ_FROM_REF(objtype, obj, orig, hr) objtype^ obj = orig;\
 hr = S_OK;
-#define GET_WRL_OBJ_FROM_OBJ(objtype, obj, orig, hr) objtype^ obj = orig;\
+#define GET_WRL_OBJ_FROM_OBJ(objtype, obj, orig, hr) objtype^ obj = safe_cast<objtype^>(orig);\
 hr = S_OK;
 #define WRL_ENUM_GET(obj, prefix, prop) obj::##prop
 #define WRL_PROP_GET(obj, prop, arg, hr) arg = obj->##prop;\
@@ -242,11 +472,18 @@ hr = S_OK;
 hr = S_OK;
 #define WRL_METHOD(obj, method, ret, hr, ...) ret = obj->##method(__VA_ARGS__);\
 hr = S_OK;
+#define WRL_METHOD_NORET_BASE(obj, method, hr) obj->##method();\
+    hr = S_OK;
+#define WRL_METHOD_NORET(obj, method, hr, ...) obj->##method(__VA_ARGS__);\
+    hr = S_OK;
 #define REF_WRL_OBJ(obj) &obj
 #define DEREF_WRL_OBJ(obj) obj
 #define DEREF_AGILE_WRL_OBJ(obj) obj.Get()
 #define DEREF_AS_NATIVE_WRL_OBJ(type, obj) reinterpret_cast<type*>(obj)
 #define PREPARE_TRANSFER_WRL_OBJ(obj) obj
+#define ACTIVATE_LOCAL_OBJ_BASE(objtype) ref new objtype()
+#define ACTIVATE_LOCAL_OBJ(objtype, ...) ref new objtype(__VA_ARGS__)
+#define ACTIVATE_EVENT_HANDLER(objtype, ...) ref new objtype(__VA_ARGS__)
 #define ACTIVATE_OBJ(rtclass, objtype, obj, hr) MAKE_WRL_OBJ(objtype) obj = ref new objtype();\
 hr = S_OK;
 #define ACTIVATE_STATIC_OBJ(rtclass, objtype, obj, hr) objtype obj;\
@@ -257,6 +494,7 @@ hr = S_OK;
 #define _String HSTRING
 #define _StringObj Microsoft::WRL::Wrappers::HString
 #define _StringReference Microsoft::WRL::Wrappers::HStringReference
+#define _StringReferenceObj Microsoft::WRL::Wrappers::HStringReference
 #define _DeviceInformationCollection ABI::Windows::Devices::Enumeration::DeviceInformationCollection
 #define _MediaCapture ABI::Windows::Media::Capture::IMediaCapture
 #define _MediaCaptureVideoPreview ABI::Windows::Media::Capture::IMediaCaptureVideoPreview
@@ -266,6 +504,7 @@ hr = S_OK;
 #define _MediaEncodingProperties ABI::Windows::Media::MediaProperties::IMediaEncodingProperties
 #define _VideoEncodingProperties ABI::Windows::Media::MediaProperties::IVideoEncodingProperties
 #define _MediaStreamType ABI::Windows::Media::Capture::MediaStreamType
+#define _AsyncInfo ABI::Windows::Foundation::IAsyncInfo
 #define _AsyncAction ABI::Windows::Foundation::IAsyncAction
 #define _AsyncOperation ABI::Windows::Foundation::IAsyncOperation
 #define _DeviceClass ABI::Windows::Devices::Enumeration::DeviceClass
@@ -282,21 +521,32 @@ hr = S_OK;
 #define _InitializeWithSettingsAsync InitializeWithSettingsAsync
 #define _FindAllAsyncDeviceClass FindAllAsyncDeviceClass
 #define _MediaExtension ABI::Windows::Media::IMediaExtension
-#define _ContextCallback Concurrency_winrt::details::_ContextCallback
-#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = var._CallInContext([__VA_ARGS__]() -> HRESULT {
-#define END_CALL_IN_CONTEXT(hr) return hr;\
-});
-#define DO_ACTION_SYNCHRONOUSLY(hr, action, ctxt) hr = CCompletionHandler<ABI::Windows::Foundation::IAsyncActionCompletedHandler, ABI::Windows::Foundation::IAsyncAction>::PerformActionSynchronously(action, ctxt)
-#define DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, action, ctxt, pResult, vectortype, elementtype, _type) hr = CCompletionHandler<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_type*>, ABI::Windows::Foundation::IAsyncOperation<_type*>>::PerformSynchronously<vectortype<elementtype*>*>(action, ctxt, pResult.GetAddressOf())
-#define BEGIN_CREATE_ASYNC(...) Concurrency_winrt::create_async([__VA_ARGS__]() -> HRESULT {
+#define BEGIN_CREATE_ASYNC(type, ...) Concurrency_winrt::create_async<type>([__VA_ARGS__]() -> HRESULT {
 #define END_CREATE_ASYNC(hr) return hr;\
 })
 #define DEFINE_TASK Concurrency_winrt::task
 #define CREATE_TASK Concurrency_winrt::create_task
-#define CREATE_OR_CONTINUE_TASK(_task, rettype, func) _task = (_task == Concurrency_winrt::task<rettype>()) ? Concurrency_winrt::create_task(func) : _task.then([func](rettype) -> rettype { return func(); });
+#define CREATE_OR_CONTINUE_TASK(_task, rettype, func) _task = (_task == Concurrency_winrt::task<rettype>()) ? Concurrency_winrt::create_task<rettype>(func) : _task.then([func](rettype, rettype* retVal) -> HRESULT { return func(retVal); });
+#define DEFINE_RET_VAL(x) x* retVal
+#define DEFINE_RET_TYPE(x) <x>
+#define DEFINE_RET_FORMAL(x) HRESULT
+#define RET_VAL(x) *retVal = x;\
+return S_OK;
+#define RET_VAL_BASE return S_OK;
+#define MAKE_STRING(str) Microsoft::WRL::Wrappers::HStringReference(L##str)
+#define GET_STL_STRING(str) std::wstring(str.GetRawBuffer(NULL))
+#define GET_STL_STRING_RAW(str) WindowsGetStringRawBuffer(str, NULL)
 #define MAKE_WRL_OBJ(x) Microsoft::WRL::ComPtr<x>
 #define MAKE_WRL_REF(x) x*
+#define MAKE_OBJ_REF(x) x
 #define MAKE_WRL_AGILE_REF(x) x*
+#define MAKE_PROPERTY_BACKING(Type, PropName) Type PropName;
+#define MAKE_PROPERTY(Type, PropName, PropValue) STDMETHODIMP get_##PropName(Type* pVal) { if (pVal) { *pVal = PropValue; } else { return E_INVALIDARG; } return S_OK; }\
+    STDMETHODIMP put_##PropName(Type Val) { PropValue = Val; return S_OK; }
+#define MAKE_PROPERTY_STRING(Type, PropName, PropValue) STDMETHODIMP get_##PropName(Type* pVal) { if (pVal) { return ::WindowsDuplicateString(PropValue.Get(), pVal); } else { return E_INVALIDARG; } }\
+    STDMETHODIMP put_##PropName(Type Val) { return PropValue.Set(Val); }
+#define MAKE_READONLY_PROPERTY(Type, PropName, PropValue) STDMETHODIMP get_##PropName(Type* pVal) { if (pVal) { *pVal = PropValue; } else { return E_INVALIDARG; } return S_OK; }
+#define THROW_INVALID_ARG RoOriginateError(E_INVALIDARG, nullptr);
 #define RELEASE_AGILE_WRL(x) if (x) { (x)->Release(); x = nullptr; }
 #define RELEASE_WRL(x) if (x) { (x)->Release(); x = nullptr; }
 #define GET_WRL_OBJ_FROM_REF(objtype, obj, orig, hr) Microsoft::WRL::ComPtr<objtype> obj;\
@@ -308,11 +558,15 @@ hr = orig.As(&obj);
 #define WRL_PROP_PUT(obj, prop, arg, hr) hr = obj->put_##prop(arg);
 #define WRL_METHOD_BASE(obj, method, ret, hr) hr = obj->##method(&ret);
 #define WRL_METHOD(obj, method, ret, hr, ...) hr = obj->##method(__VA_ARGS__, &ret);
+#define WRL_METHOD_NORET_BASE(obj, method, hr) hr = obj->##method();
 #define REF_WRL_OBJ(obj) obj.GetAddressOf()
 #define DEREF_WRL_OBJ(obj) obj.Get()
 #define DEREF_AGILE_WRL_OBJ(obj) obj
 #define DEREF_AS_NATIVE_WRL_OBJ(type, obj) obj.Get()
 #define PREPARE_TRANSFER_WRL_OBJ(obj) obj.Detach()
+#define ACTIVATE_LOCAL_OBJ_BASE(objtype) Microsoft::WRL::Make<objtype>()
+#define ACTIVATE_LOCAL_OBJ(objtype, ...) Microsoft::WRL::Make<objtype>(__VA_ARGS__)
+#define ACTIVATE_EVENT_HANDLER(objtype, ...) Microsoft::WRL::Callback<objtype>(__VA_ARGS__).Get()
 #define ACTIVATE_OBJ(rtclass, objtype, obj, hr) MAKE_WRL_OBJ(objtype) obj;\
 {\
     Microsoft::WRL::ComPtr<IActivationFactory> objFactory;\
@@ -333,272 +587,96 @@ hr = orig.As(&obj);
 }
 #endif
 
-#define GET_CURRENT_CONTEXT _ContextCallback::_CaptureCurrent()
-#define SAVE_CURRENT_CONTEXT(var) _ContextCallback var = GET_CURRENT_CONTEXT
-
-#ifdef __cplusplus_winrt
-ref class CCompletionHandler sealed
+#define _ComPtr Microsoft::WRL::ComPtr
 #else
-template <typename TCompletionHandler, typename TAction>
-class CCompletionHandler
-    : public Microsoft::WRL::RuntimeClass<
-    Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::ClassicCom>,
-    TCompletionHandler, IAgileObject, FtmBase>
-#endif
+
+template <class T>
+class ComPtr : public ATL::CComPtr<T>
 {
-    MixInHelper()
-#ifndef __cplusplus_winrt
 public:
-    CCompletionHandler() {}
-
-    STDMETHODIMP Invoke(TAction* /*asyncInfo*/, AsyncStatus /*asyncStatus*/)
+    ComPtr() throw()
     {
-        m_Event.set();
-        return S_OK;
     }
-    void wait() { m_Event.wait(); }
-#endif
-#ifdef __cplusplus_winrt
-internal:
-    template <typename TResult>
-    static TResult PerformSynchronously(Windows::Foundation::IAsyncOperation<TResult>^ asyncOp, _ContextCallback context)
-    {
-        TResult pResult;
-        context._CallInContext([asyncOp, &pResult]() { Concurrency::task<TResult> asyncTask = Concurrency::task<TResult>(asyncOp); pResult = asyncTask.get(); });
-        return pResult;
-#else
-    template <typename TResult>
-    static HRESULT PerformSynchronously(TAction* asyncOp, _ContextCallback context, TResult* pResult)
+    ComPtr(int nNull) throw() :
+        CComPtr<T>((T*)nNull)
     {
-        HRESULT hr;
-        ComPtr<CCompletionHandler<TCompletionHandler, TAction>> completeHandler = Microsoft::WRL::Make<CCompletionHandler<TCompletionHandler, TAction>>();
-        hr = context._CallInContext([&asyncOp, &completeHandler]() -> HRESULT {
-            HRESULT hr = asyncOp->put_Completed(completeHandler.Get());
-            if (FAILED(hr)) asyncOp->Release();
-            return hr;
-        });
-        if (SUCCEEDED(hr))
-            completeHandler->wait();
-        else
-            return hr;
-        hr = context._CallInContext([&asyncOp, &pResult]() -> HRESULT {
-            HRESULT hr = asyncOp->GetResults(pResult);
-            asyncOp->Release();
-            return hr;
-        });
-        return hr;
-#endif
     }
+    ComPtr(T* lp) throw() :
+        CComPtr<T>(lp)
 
-#ifdef __cplusplus_winrt
-    static void PerformActionSynchronously(Windows::Foundation::IAsyncAction^ asyncOp, _ContextCallback context)
     {
-        context._CallInContext([asyncOp](){ Concurrency::task<void>(asyncOp).get(); });
-#else
-    static HRESULT PerformActionSynchronously(TAction* asyncOp, _ContextCallback context)
+    }
+    ComPtr(_In_ const CComPtr<T>& lp) throw() :
+        CComPtr<T>(lp.p)
     {
-        HRESULT hr;
-        ComPtr<CCompletionHandler<TCompletionHandler, TAction>> completeHandler = Microsoft::WRL::Make<CCompletionHandler<TCompletionHandler, TAction>>();
-        hr = context._CallInContext([&asyncOp, &completeHandler]() -> HRESULT {
-            HRESULT hr = asyncOp->put_Completed(completeHandler.Get());
-            if (FAILED(hr)) asyncOp->Release();
-            return hr;
-        });
-        if (SUCCEEDED(hr))
-            completeHandler->wait();
-        else
-            return hr;
-        hr = context._CallInContext([&asyncOp]() -> HRESULT {
-            HRESULT hr = asyncOp->GetResults();
-            asyncOp->Release();
-            return hr;
-        });
-        return hr;
-#endif
     }
-#ifndef __cplusplus_winrt
-private:
-    Concurrency::event m_Event;
-#endif
-};
-
-#ifndef __cplusplus_winrt
-
-// Helpers for create_async validation
-//
-// A parameter lambda taking no arguments is valid
-template<typename _Ty>
-static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int) -> typename decltype(_Param(), std::true_type());
-
-// A parameter lambda taking an cancellation_token argument is valid
-template<typename _Ty>
-static auto _IsValidCreateAsync(_Ty _Param, int, int, int, ...) -> typename decltype(_Param(cancellation_token::none()), std::true_type());
-
-// A parameter lambda taking a progress report argument is valid
-template<typename _Ty>
-static auto _IsValidCreateAsync(_Ty _Param, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType()), std::true_type());
-
-// A parameter lambda taking a progress report and a cancellation_token argument is valid
-template<typename _Ty>
-static auto _IsValidCreateAsync(_Ty _Param, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), cancellation_token::none()), std::true_type());
-
-// All else is invalid
-template<typename _Ty>
-static std::false_type _IsValidCreateAsync(_Ty _Param, ...);
-
-//for task specific architecture
-//could add a CancelPending which is set when Cancel is called, return as Cancel when get_Status is called and set when a task_canceled exception is thrown
+    virtual ~ComPtr() {}
 
-extern const __declspec(selectany) WCHAR RuntimeClass_CV_CAsyncAction[] = L"cv.CAsyncAction";
-
-template<typename _Function>
-class CAsyncAction
-    : public Microsoft::WRL::RuntimeClass<
-    Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>,
-    Microsoft::WRL::Implements<ABI::Windows::Foundation::IAsyncAction>, Microsoft::WRL::AsyncBase<ABI::Windows::Foundation::IAsyncActionCompletedHandler >>
-{
-    InspectableClass(RuntimeClass_CV_CAsyncAction, BaseTrust)
-public:
-    STDMETHOD(RuntimeClassInitialize)() { return S_OK; }
-    virtual ~CAsyncAction() {}
-    CAsyncAction(const _Function &_Func) : _M_func(_Func) {
-        Start();
-    }
-    void _SetTaskCreationAddressHint(void* _SourceAddressHint)
+    T* const* GetAddressOf() const throw()
     {
-        if (!(std::is_same<Concurrency_winrt::details::_TaskTypeTraits<Concurrency_winrt::task<HRESULT>>::_AsyncKind, Concurrency_winrt::details::_TypeSelectorAsyncTask>::value))
-        {
-            // Overwrite the creation address with the return address of create_async unless the
-            // lambda returned a task. If the create async lambda returns a task, that task is reused and
-            // we want to preserve its creation address hint.
-            _M_task._SetTaskCreationAddressHint(_SourceAddressHint);
-        }
+        return &p;
     }
-    HRESULT STDMETHODCALLTYPE put_Completed(
-        /* [in] */ __RPC__in_opt ABI::Windows::Foundation::IAsyncActionCompletedHandler *handler)
+
+    T** GetAddressOf() throw()
     {
-        HRESULT hr;
-        if (SUCCEEDED(hr = PutOnComplete(handler)) && cCallbackMade_ == 0) {
-            //okay to use default implementation even for the callback as already running in context
-            //otherwise check for the alternate case and save the context
-            _M_completeDelegateContext = _ContextCallback::_CaptureCurrent();
-        }
-        return hr;
+        return &p;
     }
-    HRESULT STDMETHODCALLTYPE get_Completed(
-        /* [out][retval] */ __RPC__deref_out_opt ABI::Windows::Foundation::IAsyncActionCompletedHandler **handler) {
-        if (!handler) return E_POINTER;
-        return GetOnComplete(handler);
+
+    T** ReleaseAndGetAddressOf() throw()
+    {
+        InternalRelease();
+        return &p;
     }
-    HRESULT STDMETHODCALLTYPE GetResults(void) {
-        HRESULT hr = CheckValidStateForResultsCall();
-        if (SUCCEEDED(hr)) {
-            _M_task.get();
-        }
-        return hr;
+
+    T* Get() const throw()
+    {
+        return p;
     }
-    HRESULT OnStart() {
-        _M_task = Concurrency_winrt::task<HRESULT>(_M_func, _M_cts.get_token());
-        AddRef();
-        _M_task.then([this](Concurrency_winrt::task<HRESULT> _Antecedent) {
-            try {
-                HRESULT hr = _Antecedent.get();
-                if (FAILED(hr)) TryTransitionToError(hr);
-            }
-            catch (Concurrency::task_canceled&){
-            }
-            catch (...) {
-                TryTransitionToError(E_FAIL);
-            }
-            _FireCompletion();
-            Release();
-        });
-        return S_OK;
+    ComPtr& operator=(decltype(__nullptr)) throw()
+    {
+        InternalRelease();
+        return *this;
     }
-    void OnClose() {}
-    void OnCancel() { _M_cts.cancel(); }
-
-protected:
-    //modified for _CallInContext to support UI STA thread
-    //can wrap the base clase implementation or duplicate it but must use get_Completed to fetch the private member variable
-    virtual void _FireCompletion()
-    {
-        AddRef();
-        _M_completeDelegateContext._CallInContext([this]() -> HRESULT {
-            FireCompletion();
-            Release();
-            return S_OK;
-        });
+    ComPtr& operator=(_In_ const int nNull) throw()
+    {
+        ASSERT(nNull == 0);
+        (void)nNull;
+        InternalRelease();
+        return *this;
     }
-private:
-
-    _Function _M_func;
-    Concurrency_winrt::task<HRESULT> _M_task;
-    Concurrency::cancellation_token_source _M_cts;
-    _ContextCallback        _M_completeDelegateContext;
-};
-
-template<typename _Function>
-__declspec(noinline)
-CAsyncAction<_Function>* create_async(const _Function& _Func)
-{
-    static_assert(std::is_same<decltype(_IsValidCreateAsync(_Func, 0, 0, 0, 0)), std::true_type>::value,
-        "argument to create_async must be a callable object taking zero, one or two arguments");
-    CAsyncAction<_Function>* action = Microsoft::WRL::Make<CAsyncAction<_Function>>(_Func).Detach();
-    action->_SetTaskCreationAddressHint(_ReturnAddress());
-    return action;
-}
-#endif
-
-EXTERN_C const IID IID_IMedCapFailHandler;
-
-class DECLSPEC_UUID("CE22BEDB-0B3C-4BE0-BE8F-E53AB457EA2C") DECLSPEC_NOVTABLE IMedCapFailHandler : public IUnknown
-{
-public:
-    virtual HRESULT AddHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap) = 0;
-    virtual HRESULT RemoveHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap) = 0;
-};
-
-template<typename _Function>
-class MediaCaptureFailedHandler :
-    public Microsoft::WRL::RuntimeClass<
-    Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::ClassicCom>,
-    IMedCapFailHandler, ABI::Windows::Media::Capture::IMediaCaptureFailedEventHandler, IAgileObject, FtmBase>
-{
-public:
-    MediaCaptureFailedHandler(const _Function &_Func) : _M_func(_Func) { m_cookie.value = 0; }
-    HRESULT AddHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap)
+    unsigned long Reset()
     {
-        return pMedCap->add_Failed(this, &m_cookie);
+        return InternalRelease();
     }
-    HRESULT RemoveHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap)
+    // query for U interface
+    template<typename U>
+    HRESULT As(_Inout_ U** lp) const throw()
     {
-        return pMedCap->remove_Failed(m_cookie);
+        return p->QueryInterface(__uuidof(U), (void**)lp);
     }
-    HRESULT STDMETHODCALLTYPE Invoke(
-        ABI::Windows::Media::Capture::IMediaCapture *sender,
-        ABI::Windows::Media::Capture::IMediaCaptureFailedEventArgs *errorEventArgs)
+    // query for U interface
+    template<typename U>
+    HRESULT As(_Out_ ComPtr<U>* lp) const throw()
     {
-        (void)sender;
-        (void)errorEventArgs;
-        AddRef();
-        _M_func();
-        Release();
-        return S_OK;
+        return p->QueryInterface(__uuidof(U), reinterpret_cast<void**>(lp->ReleaseAndGetAddressOf()));
     }
-
 private:
-    _Function _M_func;
-    EventRegistrationToken m_cookie;
-};
+    unsigned long InternalRelease() throw()
+    {
+        unsigned long ref = 0;
+        T* temp = p;
 
-template<typename _Function>
-__declspec(noinline)
-MediaCaptureFailedHandler<_Function>* create_medcapfailedhandler(const _Function& _Func)
-{
-    return Microsoft::WRL::Make<MediaCaptureFailedHandler<_Function>>(_Func).Detach();
-}
+        if (temp != nullptr)
+        {
+            p = nullptr;
+            ref = temp->Release();
+        }
+
+        return ref;
+    }
+};
 
+#define _ComPtr ComPtr
 #endif
 
 template <class TBase=IMFAttributes>
@@ -946,7 +1024,7 @@ done:
     }
 
 protected:
-    ComPtr<IMFAttributes> _spAttributes;
+    _ComPtr<IMFAttributes> _spAttributes;
 };
 
 class StreamSink :
@@ -1005,11 +1083,11 @@ public:
 #ifdef HAVE_WINRT
     STDMETHOD(RuntimeClassInitialize)() { return S_OK; }
 #else
-    ULONG AddRef()
+    ULONG STDMETHODCALLTYPE AddRef()
     {
         return InterlockedIncrement(&m_cRef);
     }
-    ULONG Release()
+    ULONG STDMETHODCALLTYPE Release()
     {
         ULONG cRef = InterlockedDecrement(&m_cRef);
         if (cRef == 0)
@@ -1025,7 +1103,7 @@ public:
         if (m_spFTM == nullptr) {
             EnterCriticalSection(&m_critSec);
             if (m_spFTM == nullptr) {
-                hr = CoCreateFreeThreadedMarshaler(static_cast<IMFStreamSink*>(this), &m_spFTM);
+                hr = CoCreateFreeThreadedMarshaler((IMFStreamSink*)this, &m_spFTM);
             }
             LeaveCriticalSection(&m_critSec);
         }
@@ -1061,14 +1139,12 @@ public:
         InitializeCriticalSectionEx(&m_critSec, 3000, 0);
         ZeroMemory(&m_guiCurrentSubtype, sizeof(m_guiCurrentSubtype));
         CBaseAttributes::Initialize(0U);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::StreamSink\n");
+        DebugPrintOut(L"StreamSink::StreamSink\n");
     }
     virtual ~StreamSink() {
         DeleteCriticalSection(&m_critSec);
         assert(m_IsShutdown);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::~StreamSink\n");
+        DebugPrintOut(L"StreamSink::~StreamSink\n");
     }
 
     HRESULT Initialize()
@@ -1078,7 +1154,7 @@ public:
         hr = MFCreateEventQueue(&m_spEventQueue);
         if (SUCCEEDED(hr))
         {
-            ComPtr<IMFMediaSink> pMedSink;
+            _ComPtr<IMFMediaSink> pMedSink;
             hr = CBaseAttributes<>::GetUnknown(MF_STREAMSINK_MEDIASINKINTERFACE, __uuidof(IMFMediaSink), (LPVOID*)pMedSink.GetAddressOf());
             assert(pMedSink.Get() != NULL);
             if (SUCCEEDED(hr)) {
@@ -1102,10 +1178,8 @@ public:
     // Called when the presentation clock starts.
     HRESULT Start(MFTIME start)
     {
-        EnterCriticalSection(&m_critSec);
-
         HRESULT hr = S_OK;
-
+        EnterCriticalSection(&m_critSec);
         if (m_state != State_TypeNotSet) {
             if (start != PRESENTATION_CURRENT_POSITION)
             {
@@ -1184,7 +1258,7 @@ public:
     // Shuts down the stream sink.
     HRESULT Shutdown()
     {
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         HRESULT hr = S_OK;
         assert(!m_IsShutdown);
         hr = m_pParent->GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
@@ -1217,7 +1291,7 @@ public:
 
         if (SUCCEEDED(hr))
         {
-            ComPtr<IMFMediaSink> pMedSink;
+            _ComPtr<IMFMediaSink> pMedSink;
             hr = CBaseAttributes<>::GetUnknown(MF_STREAMSINK_MEDIASINKINTERFACE, __uuidof(IMFMediaSink), (LPVOID*)pMedSink.GetAddressOf());
             if (SUCCEEDED(hr)) {
                 *ppMediaSink = pMedSink.Detach();
@@ -1225,8 +1299,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::GetMediaSink: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::GetMediaSink: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1247,8 +1320,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::GetIdentifier: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::GetIdentifier: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1270,14 +1342,13 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::GetMediaTypeHandler: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::GetMediaTypeHandler: HRESULT=%i\n", hr);
         return hr;
     }
 
     HRESULT STDMETHODCALLTYPE ProcessSample(IMFSample *pSample) {
-        ComPtr<IMFMediaBuffer> pInput;
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFMediaBuffer> pInput;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         BYTE *pSrc = NULL;          // Source buffer.
         // Stride if the buffer does not support IMF2DBuffer
         LONGLONG hnsTime = 0;
@@ -1334,6 +1405,7 @@ public:
         /* [in] */ MFSTREAMSINK_MARKER_TYPE eMarkerType,
         /* [in] */ __RPC__in const PROPVARIANT * /*pvarMarkerValue*/,
         /* [in] */ __RPC__in const PROPVARIANT * /*pvarContextValue*/) {
+        eMarkerType;
         EnterCriticalSection(&m_critSec);
 
         HRESULT hr = S_OK;
@@ -1345,12 +1417,12 @@ public:
 
         if (SUCCEEDED(hr))
         {
+            //at shutdown will receive MFSTREAMSINK_MARKER_ENDOFSEGMENT
             hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL);
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::PlaceMarker: HRESULT=%i %s\n", hr, StreamSinkMarkerTypeMap.at(eMarkerType).c_str());
+        DebugPrintOut(L"StreamSink::PlaceMarker: HRESULT=%i %s\n", hr, StreamSinkMarkerTypeMap.at(eMarkerType).c_str());
         return hr;
     }
 
@@ -1364,8 +1436,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::Flush: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::Flush: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1378,7 +1449,7 @@ public:
 
         HRESULT hr = S_OK;
 
-        ComPtr<IMFMediaEventQueue> pQueue;
+        _ComPtr<IMFMediaEventQueue> pQueue;
 
         {
             EnterCriticalSection(&m_critSec);
@@ -1403,13 +1474,12 @@ public:
         if (SUCCEEDED(hr) && SUCCEEDED((*ppEvent)->GetType(&meType)) && meType == MEStreamSinkStopped) {
         }
         HRESULT hrStatus = S_OK;
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
         if (SUCCEEDED(hr))
             hr = (*ppEvent)->GetStatus(&hrStatus);
         if (SUCCEEDED(hr))
-            DPO->printOut(L"StreamSink::GetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str());
+            DebugPrintOut(L"StreamSink::GetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str());
         else
-            DPO->printOut(L"StreamSink::GetEvent: HRESULT=%i\n", hr);
+            DebugPrintOut(L"StreamSink::GetEvent: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1426,8 +1496,7 @@ public:
             hr = m_spEventQueue->BeginGetEvent(pCallback, punkState);
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::BeginGetEvent: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::BeginGetEvent: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1449,14 +1518,13 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
         HRESULT hrStatus = S_OK;
         if (SUCCEEDED(hr))
             hr = (*ppEvent)->GetStatus(&hrStatus);
         if (SUCCEEDED(hr))
-            DPO->printOut(L"StreamSink::EndGetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str());
+            DebugPrintOut(L"StreamSink::EndGetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str());
         else
-            DPO->printOut(L"StreamSink::EndGetEvent: HRESULT=%i\n", hr);
+            DebugPrintOut(L"StreamSink::EndGetEvent: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1475,9 +1543,8 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::QueueEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(met).c_str());
-        DPO->printOut(L"StreamSink::QueueEvent: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::QueueEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(met).c_str());
+        DebugPrintOut(L"StreamSink::QueueEvent: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1522,13 +1589,14 @@ public:
                 hr = MF_E_INVALIDTYPE;
             }
         }
+        // We don't return any "close match" types.
         if (ppMediaType)
         {
             *ppMediaType = nullptr;
         }
 
         if (ppMediaType && SUCCEEDED(hr)) {
-            ComPtr<IMFMediaType> pType;
+            _ComPtr<IMFMediaType> pType;
             hr = MFCreateMediaType(ppMediaType);
             if (SUCCEEDED(hr)) {
                 hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType);
@@ -1558,8 +1626,7 @@ public:
             }
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::IsMediaTypeSupported: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::IsMediaTypeSupported: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1583,8 +1650,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::GetMediaTypeCount: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::GetMediaTypeCount: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1609,7 +1675,7 @@ public:
             //return preferred type based on media capture library 6 elements preferred preview type
             //hr = m_spCurrentType.CopyTo(ppType);
             if (SUCCEEDED(hr)) {
-                ComPtr<IMFMediaType> pType;
+                _ComPtr<IMFMediaType> pType;
                 hr = MFCreateMediaType(ppType);
                 if (SUCCEEDED(hr)) {
                     hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType);
@@ -1641,8 +1707,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::GetMediaTypeByIndex: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::GetMediaTypeByIndex: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1674,9 +1739,6 @@ public:
 
         if (SUCCEEDED(hr))
         {
-            GUID guiMajorType;
-            pMediaType->GetMajorType(&guiMajorType);
-
             hr = MFCreateMediaType(m_spCurrentType.ReleaseAndGetAddressOf());
             if (SUCCEEDED(hr))
             {
@@ -1686,7 +1748,11 @@ public:
             {
                 hr = m_spCurrentType->GetGUID(MF_MT_SUBTYPE, &m_guiCurrentSubtype);
             }
+            GUID guid;
             if (SUCCEEDED(hr)) {
+                hr = m_spCurrentType->GetMajorType(&guid);
+            }
+            if (SUCCEEDED(hr) && guid == MFMediaType_Video) {
                 hr = MFGetAttributeSize(m_spCurrentType.Get(), MF_MT_FRAME_SIZE, &m_imageWidthInPixels, &m_imageHeightInPixels);
             }
             if (SUCCEEDED(hr))
@@ -1696,8 +1762,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::SetCurrentMediaType: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::SetCurrentMediaType: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1723,8 +1788,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::GetCurrentMediaType: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::GetCurrentMediaType: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -1737,13 +1801,12 @@ public:
             return E_INVALIDARG;
         }
 
-        ComPtr<IMFMediaType> pType;
+        _ComPtr<IMFMediaType> pType;
         hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType);
         if (SUCCEEDED(hr)) {
             hr = pType->GetMajorType(pguidMajorType);
         }
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"StreamSink::GetMajorType: HRESULT=%i\n", hr);
+        DebugPrintOut(L"StreamSink::GetMajorType: HRESULT=%i\n", hr);
         return hr;
     }
 private:
@@ -1759,10 +1822,10 @@ private:
     long m_cRef;
 #endif
     IMFAttributes*        m_pParent;
-    ComPtr<IMFMediaType>        m_spCurrentType;
-    ComPtr<IMFMediaEventQueue>  m_spEventQueue;              // Event queue
+    _ComPtr<IMFMediaType>        m_spCurrentType;
+    _ComPtr<IMFMediaEventQueue>  m_spEventQueue;              // Event queue
 
-    ComPtr<IUnknown>            m_spFTM;
+    _ComPtr<IUnknown>            m_spFTM;
     State                       m_state;
     bool                        m_fGetStartTimeFromSample;
     bool                        m_fWaitingForFirstSample;
@@ -2296,7 +2359,7 @@ class MediaSink :
     Microsoft::WRL::Implements<ABI::Windows::Media::IMediaExtension>,
     IMFMediaSink,
     IMFClockStateSink,
-    FtmBase,
+    Microsoft::WRL::FtmBase,
     CBaseAttributes<>>
 #else
     public IMFMediaSink, public IMFClockStateSink, public CBaseAttributes<>
@@ -2307,11 +2370,11 @@ class MediaSink :
 public:
 #else
 public:
-    ULONG AddRef()
+    ULONG STDMETHODCALLTYPE AddRef()
     {
         return InterlockedIncrement(&m_cRef);
     }
-    ULONG Release()
+    ULONG STDMETHODCALLTYPE Release()
     {
         ULONG cRef = InterlockedDecrement(&m_cRef);
         if (cRef == 0)
@@ -2347,13 +2410,11 @@ public:
     MediaSink() : m_IsShutdown(false), m_llStartTime(0) {
         CBaseAttributes<>::Initialize(0U);
         InitializeCriticalSectionEx(&m_critSec, 3000, 0);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::MediaSink\n");
+        DebugPrintOut(L"MediaSink::MediaSink\n");
     }
 
     virtual ~MediaSink() {
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::~MediaSink\n");
+        DebugPrintOut(L"MediaSink::~MediaSink\n");
         DeleteCriticalSection(&m_critSec);
         assert(m_IsShutdown);
     }
@@ -2376,7 +2437,7 @@ public:
             Microsoft::WRL::ComPtr<IInspectable> spInsp;
             Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> spSetting;
             Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropVal;
-            ComPtr<ABI::Windows::Media::MediaProperties::IMediaEncodingProperties> pMedEncProps;
+            Microsoft::WRL::ComPtr<ABI::Windows::Media::MediaProperties::IMediaEncodingProperties> pMedEncProps;
             UINT32 uiType = ABI::Windows::Media::Capture::MediaStreamType_VideoPreview;
 
             hr = pConfiguration->QueryInterface(IID_PPV_ARGS(&spSetting));
@@ -2385,7 +2446,7 @@ public:
             }
 
             if (SUCCEEDED(hr)) {
-                hr = spSetting->Lookup(HStringReference(MF_PROP_SAMPLEGRABBERCALLBACK).Get(), spInsp.ReleaseAndGetAddressOf());
+                hr = spSetting->Lookup(Microsoft::WRL::Wrappers::HStringReference(MF_PROP_SAMPLEGRABBERCALLBACK).Get(), spInsp.ReleaseAndGetAddressOf());
                 if (FAILED(hr)) {
                     hr = E_INVALIDARG;
                 }
@@ -2394,7 +2455,7 @@ public:
                 }
             }
             if (SUCCEEDED(hr)) {
-                hr = spSetting->Lookup(HStringReference(MF_PROP_VIDTYPE).Get(), spInsp.ReleaseAndGetAddressOf());
+                hr = spSetting->Lookup(Microsoft::WRL::Wrappers::HStringReference(MF_PROP_VIDTYPE).Get(), spInsp.ReleaseAndGetAddressOf());
                 if (FAILED(hr)) {
                     hr = E_INVALIDARG;
                 }
@@ -2405,7 +2466,7 @@ public:
                 }
             }
             if (SUCCEEDED(hr)) {
-                hr = spSetting->Lookup(HStringReference(MF_PROP_VIDENCPROPS).Get(), spInsp.ReleaseAndGetAddressOf());
+                hr = spSetting->Lookup(Microsoft::WRL::Wrappers::HStringReference(MF_PROP_VIDENCPROPS).Get(), spInsp.ReleaseAndGetAddressOf());
                 if (FAILED(hr)) {
                     hr = E_INVALIDARG;
                 }
@@ -2480,14 +2541,13 @@ public:
 
             case ABI::Windows::Foundation::PropertyType_String:
             {
-                                                                  HSTRING value;
-                                                                  hr = pValue->GetString(&value);
+                        Microsoft::WRL::Wrappers::HString value;
+                        hr = pValue->GetString(value.GetAddressOf());
                                                                   if (SUCCEEDED(hr))
                                                                   {
                                                                       UINT32 len = 0;
-                                                                      LPCWSTR szValue = WindowsGetStringRawBuffer(value, &len);
+                            LPCWSTR szValue = WindowsGetStringRawBuffer(value.Get(), &len);
                                                                       hr = pAttr->SetString(guidKey, szValue);
-                                                                      WindowsDeleteString(value);
                                                                   }
             }
                 break;
@@ -2516,7 +2576,7 @@ public:
 
             case ABI::Windows::Foundation::PropertyType_Inspectable:
             {
-                                                                       ComPtr<IInspectable> value;
+                                                                       Microsoft::WRL::ComPtr<IInspectable> value;
                                                                        hr = TYPE_E_TYPEMISMATCH;
                                                                        if (SUCCEEDED(hr))
                                                                        {
@@ -2534,10 +2594,10 @@ public:
     static HRESULT ConvertPropertiesToMediaType(_In_ ABI::Windows::Media::MediaProperties::IMediaEncodingProperties *pMEP, _Outptr_ IMFMediaType **ppMT)
     {
         HRESULT hr = S_OK;
-        ComPtr<IMFMediaType> spMT;
-        ComPtr<ABI::Windows::Foundation::Collections::IMap<GUID, IInspectable*>> spMap;
-        ComPtr<ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterable;
-        ComPtr<ABI::Windows::Foundation::Collections::IIterator<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterator;
+        _ComPtr<IMFMediaType> spMT;
+        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IMap<GUID, IInspectable*>> spMap;
+        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterable;
+        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IIterator<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterator;
 
         if (pMEP == nullptr || ppMT == nullptr)
         {
@@ -2545,7 +2605,7 @@ public:
         }
         *ppMT = nullptr;
 
-        hr = pMEP->get_Properties(&spMap);
+                hr = pMEP->get_Properties(spMap.GetAddressOf());
 
         if (SUCCEEDED(hr))
         {
@@ -2568,9 +2628,9 @@ public:
 
         while (hasCurrent)
         {
-            ComPtr<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*> > spKeyValuePair;
-            ComPtr<IInspectable> spValue;
-            ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue;
+            Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*> > spKeyValuePair;
+            Microsoft::WRL::ComPtr<IInspectable> spValue;
+            Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue;
             GUID guidKey;
 
             hr = spIterator->get_Current(&spKeyValuePair);
@@ -2609,8 +2669,8 @@ public:
 
         if (SUCCEEDED(hr))
         {
-            ComPtr<IInspectable> spValue;
-            ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue;
+            Microsoft::WRL::ComPtr<IInspectable> spValue;
+            Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue;
             GUID guiMajorType;
 
             hr = spMap->Lookup(MF_MT_MAJOR_TYPE, spValue.GetAddressOf());
@@ -2639,12 +2699,12 @@ public:
 
         return hr;
     }
-    HRESULT SetMediaStreamProperties(
-        ABI::Windows::Media::Capture::MediaStreamType MediaStreamType,
+            //this should be passed through SetProperties!
+            HRESULT SetMediaStreamProperties(ABI::Windows::Media::Capture::MediaStreamType MediaStreamType,
         _In_opt_ ABI::Windows::Media::MediaProperties::IMediaEncodingProperties *mediaEncodingProperties)
     {
         HRESULT hr = S_OK;
-        ComPtr<IMFMediaType> spMediaType;
+        _ComPtr<IMFMediaType> spMediaType;
 
         if (MediaStreamType != ABI::Windows::Media::Capture::MediaStreamType_VideoPreview &&
             MediaStreamType != ABI::Windows::Media::Capture::MediaStreamType_VideoRecord &&
@@ -2657,7 +2717,7 @@ public:
 
         if (mediaEncodingProperties != nullptr)
         {
-            ComPtr<IMFStreamSink> spStreamSink;
+            _ComPtr<IMFStreamSink> spStreamSink;
             hr = ConvertPropertiesToMediaType(mediaEncodingProperties, &spMediaType);
             if (SUCCEEDED(hr))
             {
@@ -2678,18 +2738,18 @@ public:
         if (pdwCharacteristics == NULL) return E_INVALIDARG;
         EnterCriticalSection(&m_critSec);
         if (SUCCEEDED(hr = CheckShutdown())) {
-            *pdwCharacteristics = MEDIASINK_FIXED_STREAMS;
+                    //if had an activation object for the sink, shut down would be managed and MF_STREAM_SINK_SUPPORTS_ROTATION appears to be setable to TRUE
+                    *pdwCharacteristics = MEDIASINK_FIXED_STREAMS;// | MEDIASINK_REQUIRE_REFERENCE_MEDIATYPE;
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::GetCharacteristics: HRESULT=%i\n", hr);
-        return S_OK;
+        DebugPrintOut(L"MediaSink::GetCharacteristics: HRESULT=%i\n", hr);
+        return hr;
     }
 
     HRESULT STDMETHODCALLTYPE AddStreamSink(
         DWORD dwStreamSinkIdentifier, IMFMediaType * /*pMediaType*/, IMFStreamSink **ppStreamSink) {
-        ComPtr<IMFStreamSink> spMFStream;
-        ComPtr<ICustomStreamSink> pStream;
+        _ComPtr<IMFStreamSink> spMFStream;
+        _ComPtr<ICustomStreamSink> pStream;
         EnterCriticalSection(&m_critSec);
         HRESULT hr = CheckShutdown();
 
@@ -2729,7 +2789,7 @@ public:
         }
 
         // Initialize the stream.
-        ComPtr<IMFAttributes> pAttr;
+        _ComPtr<IMFAttributes> pAttr;
         if (SUCCEEDED(hr)) {
             hr = pStream.As(&pAttr);
         }
@@ -2752,7 +2812,7 @@ public:
             for (; pos != posEnd; pos = m_streams.Next(pos))
             {
                 DWORD dwCurrId;
-                ComPtr<IMFStreamSink> spCurr;
+                _ComPtr<IMFStreamSink> spCurr;
                 hr = m_streams.GetItemPos(pos, &spCurr);
                 if (FAILED(hr))
                 {
@@ -2781,8 +2841,7 @@ public:
             *ppStreamSink = spMFStream.Detach();
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::AddStreamSink: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::AddStreamSink: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -2791,7 +2850,7 @@ public:
         HRESULT hr = CheckShutdown();
         ComPtrList<IMFStreamSink>::POSITION pos = m_streams.FrontPosition();
         ComPtrList<IMFStreamSink>::POSITION endPos = m_streams.EndPosition();
-        ComPtr<IMFStreamSink> spStream;
+        _ComPtr<IMFStreamSink> spStream;
 
         if (SUCCEEDED(hr))
         {
@@ -2821,11 +2880,18 @@ public:
         if (SUCCEEDED(hr))
         {
             hr = m_streams.Remove(pos, nullptr);
-            static_cast<StreamSink *>(spStream.Get())->Shutdown();
+                    _ComPtr<ICustomStreamSink> spCustomSink;
+#ifdef HAVE_WINRT
+                    spCustomSink = static_cast<StreamSink*>(spStream.Get());
+                    hr = S_OK;
+#else
+                    hr = spStream.As(&spCustomSink);
+#endif
+                    if (SUCCEEDED(hr))
+                        hr = spCustomSink->Shutdown();
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::RemoveStreamSink: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::RemoveStreamSink: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -2845,8 +2911,7 @@ public:
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::GetStreamSinkCount: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::GetStreamSinkCount: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -2857,7 +2922,7 @@ public:
             return E_INVALIDARG;
         }
 
-        ComPtr<IMFStreamSink> spStream;
+        _ComPtr<IMFStreamSink> spStream;
         EnterCriticalSection(&m_critSec);
         DWORD cStreams = m_streams.GetCount();
 
@@ -2894,8 +2959,7 @@ public:
             *ppStreamSink = spStream.Detach();
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::GetStreamSinkByIndex: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::GetStreamSinkByIndex: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -2908,7 +2972,7 @@ public:
 
         EnterCriticalSection(&m_critSec);
         HRESULT hr = CheckShutdown();
-        ComPtr<IMFStreamSink> spResult;
+        _ComPtr<IMFStreamSink> spResult;
 
         if (SUCCEEDED(hr))
         {
@@ -2917,7 +2981,7 @@ public:
 
             for (; pos != endPos; pos = m_streams.Next(pos))
             {
-                ComPtr<IMFStreamSink> spStream;
+                _ComPtr<IMFStreamSink> spStream;
                 hr = m_streams.GetItemPos(pos, &spStream);
                 DWORD dwId;
 
@@ -2950,8 +3014,7 @@ public:
             *ppStreamSink = spResult.Detach();
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::GetStreamSinkById: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::GetStreamSinkById: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -2976,7 +3039,7 @@ public:
             }
         }
 
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         if (SUCCEEDED(hr)) {
             // Release the pointer to the old clock.
             // Store the pointer to the new clock.
@@ -2986,8 +3049,7 @@ public:
         LeaveCriticalSection(&m_critSec);
         if (SUCCEEDED(hr))
             hr = pSampleCallback->OnSetPresentationClock(pPresentationClock);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::SetPresentationClock: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::SetPresentationClock: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -3010,8 +3072,7 @@ public:
             }
         }
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::GetPresentationClock: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::GetPresentationClock: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -3025,13 +3086,16 @@ public:
             m_streams.Clear();
             m_spClock.ReleaseAndGetAddressOf();
 
+                    _ComPtr<IMFMediaType> pType;
+                    hr = CBaseAttributes<>::GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)pType.GetAddressOf());
+                    if (SUCCEEDED(hr)) {
             hr = DeleteItem(MF_MEDIASINK_PREFERREDTYPE);
+                    }
             m_IsShutdown = true;
         }
 
         LeaveCriticalSection(&m_critSec);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::Shutdown: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::Shutdown: HRESULT=%i\n", hr);
         return hr;
     }
     class ShutdownFunc
@@ -3039,8 +3103,16 @@ public:
     public:
         HRESULT operator()(IMFStreamSink *pStream) const
         {
-            static_cast<StreamSink *>(pStream)->Shutdown();
-            return S_OK;
+                    _ComPtr<ICustomStreamSink> spCustomSink;
+                    HRESULT hr;
+#ifdef HAVE_WINRT
+                    spCustomSink = static_cast<StreamSink*>(pStream);
+#else
+                    hr = pStream->QueryInterface(IID_PPV_ARGS(spCustomSink.GetAddressOf()));
+                    if (FAILED(hr)) return hr;
+#endif
+                    hr = spCustomSink->Shutdown();
+                    return hr;
         }
     };
 
@@ -3054,7 +3126,16 @@ public:
 
         HRESULT operator()(IMFStreamSink *pStream) const
         {
-            return static_cast<StreamSink *>(pStream)->Start(_llStartTime);
+                    _ComPtr<ICustomStreamSink> spCustomSink;
+                    HRESULT hr;
+#ifdef HAVE_WINRT
+                    spCustomSink = static_cast<StreamSink*>(pStream);
+#else
+                    hr = pStream->QueryInterface(IID_PPV_ARGS(spCustomSink.GetAddressOf()));
+                    if (FAILED(hr)) return hr;
+#endif
+                    hr = spCustomSink->Start(_llStartTime);
+                    return hr;
         }
 
         LONGLONG _llStartTime;
@@ -3065,7 +3146,16 @@ public:
     public:
         HRESULT operator()(IMFStreamSink *pStream) const
         {
-            return static_cast<StreamSink *>(pStream)->Stop();
+                    _ComPtr<ICustomStreamSink> spCustomSink;
+                    HRESULT hr;
+#ifdef HAVE_WINRT
+                    spCustomSink = static_cast<StreamSink*>(pStream);
+#else
+                    hr = pStream->QueryInterface(IID_PPV_ARGS(spCustomSink.GetAddressOf()));
+                    if (FAILED(hr)) return hr;
+#endif
+                    hr = spCustomSink->Stop();
+                    return hr;
         }
     };
 
@@ -3078,7 +3168,7 @@ public:
 
         for (; pos != endPos; pos = col.Next(pos))
         {
-            ComPtr<T> spStream;
+            _ComPtr<T> spStream;
 
             hr = col.GetItemPos(pos, &spStream);
             if (FAILED(hr))
@@ -3104,14 +3194,13 @@ public:
             m_llStartTime = llClockStartOffset;
             hr = ForEach(m_streams, StartFunc(llClockStartOffset));
         }
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         if (SUCCEEDED(hr))
             hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
         LeaveCriticalSection(&m_critSec);
         if (SUCCEEDED(hr))
             hr = pSampleCallback->OnClockStart(hnsSystemTime, llClockStartOffset);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::OnClockStart: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::OnClockStart: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -3125,38 +3214,35 @@ public:
             // Stop each stream
             hr = ForEach(m_streams, StopFunc());
         }
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         if (SUCCEEDED(hr))
             hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
         LeaveCriticalSection(&m_critSec);
         if (SUCCEEDED(hr))
             hr = pSampleCallback->OnClockStop(hnsSystemTime);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::OnClockStop: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::OnClockStop: HRESULT=%i\n", hr);
         return hr;
     }
 
     HRESULT STDMETHODCALLTYPE OnClockPause(
         MFTIME hnsSystemTime) {
         HRESULT hr;
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
         if (SUCCEEDED(hr))
             hr = pSampleCallback->OnClockPause(hnsSystemTime);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::OnClockPause: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::OnClockPause: HRESULT=%i\n", hr);
         return hr;
     }
 
     HRESULT STDMETHODCALLTYPE OnClockRestart(
         MFTIME hnsSystemTime) {
            HRESULT hr;
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
         if (SUCCEEDED(hr))
             hr = pSampleCallback->OnClockRestart(hnsSystemTime);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::OnClockRestart: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::OnClockRestart: HRESULT=%i\n", hr);
         return hr;
     }
 
@@ -3164,12 +3250,11 @@ public:
         MFTIME hnsSystemTime,
         float flRate) {
            HRESULT hr;
-        ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
+        _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
         hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
         if (SUCCEEDED(hr))
             hr = pSampleCallback->OnClockSetRate(hnsSystemTime, flRate);
-        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-        DPO->printOut(L"MediaSink::OnClockSetRate: HRESULT=%i\n", hr);
+        DebugPrintOut(L"MediaSink::OnClockSetRate: HRESULT=%i\n", hr);
         return hr;
     }
 private:
@@ -3179,7 +3264,7 @@ private:
     CRITICAL_SECTION            m_critSec;
     bool                        m_IsShutdown;
     ComPtrList<IMFStreamSink>    m_streams;
-    ComPtr<IMFPresentationClock>    m_spClock;
+    _ComPtr<IMFPresentationClock>    m_spClock;
     LONGLONG                        m_llStartTime;
 };
 
index 29dccbd..1243bae 100644 (file)
 
 #pragma once
 
+#ifndef _PPLTASKS_WINRT_H
+#define _PPLTASKS_WINRT_H
+
 #include <concrt.h>
 #include <ppltasks.h>
+#if _MSC_VER >= 1800
+#include <pplconcrt.h>
+
+// Cannot build using a compiler that is older than dev10 SP1
+#ifdef _MSC_VER
+#if _MSC_FULL_VER < 160040219 /*IFSTRIP=IGN*/
+#error ERROR: Visual Studio 2010 SP1 or later is required to build ppltasks
+#endif /*IFSTRIP=IGN*/
+#endif
+#else
 #include <ppl.h>
+#endif
 #include <functional>
 #include <vector>
 #include <utility>
 #include <exception>
+#if _MSC_VER >= 1800
+#include <algorithm>
+#endif
 
 #ifndef __cplusplus_winrt
 
 #include <wrl\implements.h>
 #include <wrl\async.h>
+#if _MSC_VER >= 1800
+#include "agile_wrl.h"
+#endif
 #include <windows.foundation.h>
 #include <ctxtcall.h>
 
 #ifndef _UITHREADCTXT_SUPPORT
 
-#ifdef WINAPI_FAMILY
+#ifdef WINAPI_FAMILY /*IFSTRIP=IGN*/
 
 // It is safe to include winapifamily as WINAPI_FAMILY was defined by the user
 #include <winapifamily.h>
 #elif WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP /*IFSTRIP=IGN*/
     // UI thread context support is not required for desktop and Windows Store apps
     #define _UITHREADCTXT_SUPPORT 0
-#else
+#else  /* WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP */
     #define _UITHREADCTXT_SUPPORT 1
-#endif
+#endif  /* WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP */
 
-#else
+#else   /* WINAPI_FAMILY */
     // Not supported without a WINAPI_FAMILY setting.
     #define _UITHREADCTXT_SUPPORT 0
-#endif // #ifdef WINAPI_FAMILY
+#endif  /* WINAPI_FAMILY */
 
-#endif // #ifndef _UITHREADCTXT_SUPPORT
+#endif  /* _UITHREADCTXT_SUPPORT */
 
 #if _UITHREADCTXT_SUPPORT
 #include <uithreadctxt.h>
-#endif // _UITHREADCTXT_SUPPORT
+#endif  /* _UITHREADCTXT_SUPPORT */
 
 #pragma detect_mismatch("_PPLTASKS_WITH_WINRT", "0")
+
+#ifdef _DEBUG
+#define _DBG_ONLY(X) X
+#else
+#define _DBG_ONLY(X)
+#endif // #ifdef _DEBUG
+
+// std::copy_exception changed to std::make_exception_ptr from VS 2010 to VS 11.
+#ifdef _MSC_VER
+#if _MSC_VER < 1700 /*IFSTRIP=IGN*/
+namespace std
+{
+    template<class _E> exception_ptr make_exception_ptr(_E _Except)
+    {
+        return copy_exception(_Except);
+    }
+}
+#endif
+#ifndef _PPLTASK_ASYNC_LOGGING
+#if _MSC_VER >= 1800 && defined(__cplusplus_winrt)
+#define _PPLTASK_ASYNC_LOGGING 1  // Only enable async logging under dev12 winrt
+#else
+#define _PPLTASK_ASYNC_LOGGING 0
+#endif
+#endif
+#endif
+
 #pragma pack(push,_CRT_PACKING)
 
 #pragma warning(push)
 #pragma warning(disable: 28197)
 #pragma warning(disable: 4100) // Unreferenced formal parameter - needed for document generation
+#if _MSC_VER >= 1800
+#pragma warning(disable: 4127) // constant express in if condition - we use it for meta programming
+#else
 #pragma warning(disable: 4702) // Unreachable code - it is caused by user lambda throw exceptions
+#endif
 
 // All CRT public header files are required to be protected from the macro new
 #pragma push_macro("new")
 #undef new
 
-#define __is_valid_winrt_type(_Type) (std::is_void<_Type>::value || \
-    std::is_same<_Type, BYTE>::value || \
-    std::is_same<_Type, INT16>::value || \
-    std::is_same<_Type, UINT16>::value || \
-    std::is_same<_Type, INT32>::value || \
-    std::is_same<_Type, UINT32>::value || \
-    std::is_same<_Type, INT64>::value || \
-    std::is_same<_Type, UINT64>::value || \
-    std::is_same<_Type, FLOAT>::value || \
-    std::is_same<_Type, DOUBLE>::value || \
-    std::is_same<_Type, WCHAR>::value || \
-    std::is_same<_Type, boolean>::value || \
-    std::is_same<_Type, HSTRING>::value || \
-    std::is_same<_Type, IInspectable *>::value || \
-    std::is_same<_Type, GUID>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::DateTime>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::TimeSpan>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::Point>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::Size>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::Rect>::value || \
-    std::is_same<_Type, BYTE*>::value || \
-    std::is_same<_Type, INT16*>::value || \
-    std::is_same<_Type, UINT16*>::value || \
-    std::is_same<_Type, INT32*>::value || \
-    std::is_same<_Type, UINT32*>::value || \
-    std::is_same<_Type, INT64*>::value || \
-    std::is_same<_Type, UINT64*>::value || \
-    std::is_same<_Type, FLOAT*>::value || \
-    std::is_same<_Type, DOUBLE*>::value || \
-    std::is_same<_Type, WCHAR*>::value || \
-    std::is_same<_Type, boolean*>::value || \
-    std::is_same<_Type, HSTRING*>::value || \
-    std::is_same<_Type, IInspectable **>::value || \
-    std::is_same<_Type, GUID*>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::DateTime*>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::TimeSpan*>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::Point*>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::Size*>::value || \
-    std::is_same<_Type, ABI::Windows::Foundation::Rect*>::value)
+// stuff ported from Dev11 CRT
+// NOTE: this doesn't actually match std::declval. it behaves differently for void!
+// so don't blindly change it to std::declval.
+namespace stdx
+{
+    template<class _T>
+    _T&& declval();
+}
 
 /// <summary>
 ///     The <c>Concurrency_winrt</c> namespace provides classes and functions that give you access to the Concurrency Runtime,
 /**/
 namespace Concurrency_winrt
 {
+    // In debug builds, default to 10 frames, unless this is overridden prior to #includ'ing ppltasks.h.  In retail builds, default to only one frame.
+#ifndef PPL_TASK_SAVE_FRAME_COUNT
+#ifdef _DEBUG
+#define PPL_TASK_SAVE_FRAME_COUNT 10
+#else
+#define PPL_TASK_SAVE_FRAME_COUNT 1
+#endif
+#endif
+
+    /// <summary>
+    /// Helper macro to determine how many stack frames need to be saved. When any number less or equal to 1 is specified,
+    /// only one frame is captured and no stackwalk will be involved. Otherwise, the number of callstack frames will be captured.
+    /// </summary>
+    /// <ramarks>
+    /// This needs to be defined as a macro rather than a function so that if we're only gathering one frame, _ReturnAddress()
+    /// will evaluate to client code, rather than a helper function inside of _TaskCreationCallstack, itself.
+    /// </remarks>
+#ifdef _CAPTURE_CALLSTACK
+#undef _CAPTURE_CALLSTACK
+#endif
+#if PPL_TASK_SAVE_FRAME_COUNT > 1
+#if !defined(_DEBUG)
+#pragma message ("WARNING: Redefinning PPL_TASK_SAVE_FRAME_COUNT under Release build for non-desktop applications is not supported; only one frame will be captured!")
+#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureSingleFrameCallstack(_ReturnAddress())
+#else
+#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureMultiFramesCallstack(PPL_TASK_SAVE_FRAME_COUNT)
+#endif
+#else
+#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureSingleFrameCallstack(_ReturnAddress())
+#endif
 /// <summary>
+
 ///     A type that represents the terminal state of a task. Valid values are <c>completed</c> and <c>canceled</c>.
 /// </summary>
 /// <seealso cref="task Class"/>
@@ -151,7 +202,18 @@ template <> class task<void>;
 /// <seealso cref="cancellation_token Class"/>
 /// <seealso cref="cancel_current_task Function"/>
 /**/
-_CRTIMP2 bool __cdecl is_task_cancellation_requested();
+#if _MSC_VER >= 1800
+inline bool __cdecl is_task_cancellation_requested()
+{
+    return ::Concurrency::details::_TaskCollection_t::_Is_cancellation_requested();
+}
+#else
+inline bool __cdecl is_task_cancellation_requested()
+{
+    // ConcRT scheduler under the hood is using TaskCollection, which is same as task_group
+    return ::Concurrency::is_current_task_group_canceling();
+}
+#endif
 
 /// <summary>
 ///     Cancels the currently executing task. This function can be called from within the body of a task to abort the
@@ -164,10 +226,56 @@ _CRTIMP2 bool __cdecl is_task_cancellation_requested();
 /// <seealso cref="task Class"/>
 /// <seealso cref="is_task_cancellation_requested"/>
 /**/
-_CRTIMP2 __declspec(noreturn) void __cdecl cancel_current_task();
+//#if _MSC_VER >= 1800
+inline __declspec(noreturn) void __cdecl cancel_current_task()
+{
+    throw Concurrency::task_canceled();
+}
+//#else
+//_CRTIMP2 __declspec(noreturn) void __cdecl cancel_current_task();
+//#endif
 
 namespace details
 {
+#if _MSC_VER >= 1800
+    /// <summary>
+    ///     Callstack container, which is used to capture and preserve callstacks in ppltasks.
+    ///     Members of this class is examined by vc debugger, thus there will be no public access methods.
+    ///     Please note that names of this class should be kept stable for debugger examining.
+    /// </summary>
+    class _TaskCreationCallstack
+    {
+    private:
+        // If _M_SingleFrame != nullptr, there will be only one frame of callstacks, which is stored in _M_SingleFrame;
+        // otherwise, _M_Frame will store all the callstack frames.
+        void* _M_SingleFrame;
+        std::vector<void *> _M_frames;
+    public:
+        _TaskCreationCallstack()
+        {
+            _M_SingleFrame = nullptr;
+        }
+
+        // Store one frame of callstack. This function works for both Debug / Release CRT.
+        static _TaskCreationCallstack _CaptureSingleFrameCallstack(void *_SingleFrame)
+        {
+            _TaskCreationCallstack _csc;
+            _csc._M_SingleFrame = _SingleFrame;
+            return _csc;
+        }
+
+        // Capture _CaptureFrames number of callstack frames. This function only work properly for Desktop or Debug CRT.
+        __declspec(noinline)
+            static _TaskCreationCallstack _CaptureMultiFramesCallstack(size_t _CaptureFrames)
+        {
+                _TaskCreationCallstack _csc;
+                _csc._M_frames.resize(_CaptureFrames);
+                // skip 2 frames to make sure callstack starts from user code
+                _csc._M_frames.resize(::Concurrency::details::platform::CaptureCallstack(&_csc._M_frames[0], 2, _CaptureFrames));
+                return _csc;
+        }
+    };
+#endif
     typedef UINT32 _Unit_type;
 
     struct _TypeSelectorNoAsync {};
@@ -231,12 +339,12 @@ namespace details
         typedef _Type _Value;
     };
 
-    struct _NonUserType { public: int _Dummy; };
+    //struct _NonUserType { public: int _Dummy; };
 
     template <typename _Type, bool _IsValueTypeOrRefType = __is_valid_winrt_type(_Type)>
     struct _ValueTypeOrRefType
     {
-        typedef _NonUserType _Value;
+        typedef _Unit_type _Value;
     };
 
     template <typename _Type>
@@ -245,6 +353,18 @@ namespace details
         typedef _Type _Value;
     };
 
+    template <typename _Ty>
+    _Ty _UnwrapAsyncActionWithProgressSelector(ABI::Windows::Foundation::IAsyncActionWithProgress_impl<_Ty>*);
+
+    template <typename _Ty>
+    _Ty _UnwrapAsyncActionWithProgressSelector(...);
+
+    template <typename _Ty, typename _Progress>
+    _Progress _UnwrapAsyncOperationWithProgressProgressSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress_impl<_Ty, _Progress>*);
+
+    template <typename _Ty, typename _Progress>
+    _Progress _UnwrapAsyncOperationWithProgressProgressSelector(...);
+
     template <typename _T1, typename _T2>
     _T2 _ProgressTypeSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*);
 
@@ -254,54 +374,59 @@ namespace details
     template <typename _Type>
     struct _GetProgressType
     {
-        typedef decltype(_ProgressTypeSelector(std::declval<_Type>())) _Value;
+        typedef decltype(_ProgressTypeSelector(stdx::declval<_Type>())) _Value;
     };
 
-    template <template <typename> class F>
-    struct conversion_tester
-    {
-        template <typename T>
-        conversion_tester(const F<T> &);
-    };
+    template <typename _T>
+    _TypeSelectorAsyncOperation _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperation<_T>*);
 
-    template <template <typename, typename> class F>
-    struct conversion_tester2
-    {
-        template <typename T0, typename T1>
-        conversion_tester2(const F<T0, T1> &);
-    };
+    _TypeSelectorAsyncAction _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncAction*);
 
-    template <class From, template <typename> class To>
-    struct is_instance_of
-    {
-        static const bool value = std::is_convertible<From, conversion_tester<To>>::value;
-    };
+    template <typename _T1, typename _T2>
+    _TypeSelectorAsyncOperationWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*);
 
-    template <class From, template <typename, typename> class To>
-    struct is_instance_of2
-    {
-        static const bool value = std::is_convertible<From, conversion_tester2<To>>::value;
-    };
+    template <typename _T>
+    _TypeSelectorAsyncActionWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T>*);
 
     template <typename _Type>
     struct _IsIAsyncInfo
     {
-        static const bool _Value = std::is_same<ABI::Windows::Foundation::IAsyncAction*, typename _Unhat<_Type>::_Value>::value ||
-            is_instance_of<_Type, ABI::Windows::Foundation::IAsyncOperation>::value ||
-            is_instance_of2<_Type, ABI::Windows::Foundation::IAsyncOperationWithProgress>::value ||
-            is_instance_of<_Type, ABI::Windows::Foundation::IAsyncActionWithProgress>::value;
+        static const bool _Value = std::is_base_of<ABI::Windows::Foundation::IAsyncInfo, typename _Unhat<_Type>::_Value>::value ||
+            std::is_same<_TypeSelectorAsyncAction, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value ||
+            std::is_same<_TypeSelectorAsyncOperation, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value ||
+            std::is_same<_TypeSelectorAsyncOperationWithProgress, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value ||
+            std::is_same<_TypeSelectorAsyncActionWithProgress, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value;
     };
 
-    template <typename _T>
-    _TypeSelectorAsyncOperation _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperation<_T>*);
+    template <>
+    struct _IsIAsyncInfo<void>
+    {
+        static const bool _Value = false;
+    };
 
-    _TypeSelectorAsyncAction _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncAction*);
+    template <typename _Ty>
+    _Ty _UnwrapAsyncOperationSelector(ABI::Windows::Foundation::IAsyncOperation_impl<_Ty>*);
 
-    template <typename _T1, typename _T2>
-    _TypeSelectorAsyncOperationWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*);
+    template <typename _Ty>
+    _Ty _UnwrapAsyncOperationSelector(...);
 
-    template <typename _T>
-    _TypeSelectorAsyncActionWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T>*);
+    template <typename _Ty, typename _Progress>
+    _Ty _UnwrapAsyncOperationWithProgressSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress_impl<_Ty, _Progress>*);
+
+    template <typename _Ty, typename _Progress>
+    _Ty _UnwrapAsyncOperationWithProgressSelector(...);
+
+    // Unwrap functions for asyncOperations
+    template<typename _Ty>
+    auto _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperation<_Ty>*) -> typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_Ty>*>()))>::type;
+
+    void _GetUnwrappedType(ABI::Windows::Foundation::IAsyncAction*);
+
+    template<typename _Ty, typename _Progress>
+    auto _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Ty, _Progress>*) -> typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Ty, _Progress>*>()))>::type;
+
+    template<typename _Progress>
+    void _GetUnwrappedType(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>*);
 
     template <typename _T>
     _T _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperation<_T>*);
@@ -320,7 +445,8 @@ namespace details
     struct _TaskTypeTraits
     {
         typedef typename details::_UnwrapTaskType<_Type>::_Type _TaskRetType;
-        typedef decltype(_AsyncOperationKindSelector(std::declval<_Type>())) _AsyncKind;
+        typedef _TaskRetType _TaskRetType_abi;
+        typedef decltype(_AsyncOperationKindSelector(stdx::declval<_Type>())) _AsyncKind;
         typedef typename details::_NormalizeVoidToUnitType<_TaskRetType>::_Type _NormalizedTaskRetType;
 
         static const bool _IsAsyncTask = _IsAsync;
@@ -330,21 +456,25 @@ namespace details
     template<typename _Type>
     struct _TaskTypeTraits<_Type, true>
     {
-        typedef decltype(_ReturnAsyncOperationKindSelector(std::declval<_Type>())) _TaskRetType;
+        typedef decltype(_ReturnAsyncOperationKindSelector(stdx::declval<_Type>())) _TaskRetType;
+        typedef decltype(_GetUnwrappedType(stdx::declval<_Type>())) _TaskRetType_abi;
         typedef _TaskRetType _NormalizedTaskRetType;
-        typedef decltype(std::is_same<_Type, ABI::Windows::Foundation::IAsyncAction*>::value ? _TypeSelectorAsyncAction : _AsyncOperationKindSelector((_Type)nullptr)) _AsyncKind;
+        typedef decltype(_AsyncOperationKindSelector(stdx::declval<_Type>())) _AsyncKind;
 
         static const bool _IsAsyncTask = true;
         static const bool _IsUnwrappedTaskOrAsync = details::_IsUnwrappedAsyncSelector<_AsyncKind>::_Value;
     };
 
-    template <typename _Function> auto _IsCallable(_Function _Func, int) -> decltype(_Func(), std::true_type()) { (void)_Func; return std::true_type(); }
-    template <typename _Function> std::false_type _IsCallable(_Function, ...) { return std::false_type(); }
+    template <typename _ReturnType, typename _Function> auto _IsCallable(_Function _Func, int, int, int) -> decltype(_Func(stdx::declval<task<_ReturnType>*>()), std::true_type()) { (void)_Func; return std::true_type(); }
+    template <typename _ReturnType, typename _Function> auto _IsCallable(_Function _Func, int, int, ...) -> decltype(_Func(stdx::declval<_ReturnType*>()), std::true_type()) { (void)_Func; return std::true_type(); }
+    template <typename _ReturnType, typename _Function> auto _IsCallable(_Function _Func, int, ...) -> decltype(_Func(), std::true_type()) { (void)_Func; return std::true_type(); }
+    template <typename _ReturnType, typename _Function> std::false_type _IsCallable(_Function, ...) { return std::false_type(); }
 
     template <>
     struct _TaskTypeTraits<void>
     {
         typedef void _TaskRetType;
+        typedef void _TaskRetType_abi;
         typedef _TypeSelectorNoAsync _AsyncKind;
         typedef _Unit_type _NormalizedTaskRetType;
 
@@ -352,160 +482,637 @@ namespace details
         static const bool _IsUnwrappedTaskOrAsync = false;
     };
 
-    template<typename _Type>
-    task<_Type> _To_task(_Type t);
+    // ***************************************************************************
+    // Template type traits and helpers for async production APIs:
+    //
 
-    task<void> _To_task();
+    struct _ZeroArgumentFunctor { };
+    struct _OneArgumentFunctor { };
+    struct _TwoArgumentFunctor { };
+    struct _ThreeArgumentFunctor { };
 
-    struct _BadContinuationParamType{};
+    // ****************************************
+    // CLASS TYPES:
 
-    template <typename _Function, typename _Type> auto _ReturnTypeHelper(_Type t, _Function _Func, int, int) -> decltype(_Func(_To_task(t)));
-    template <typename _Function, typename _Type> auto _ReturnTypeHelper(_Type t, _Function _Func, int, ...) -> decltype(_Func(t));
-    template <typename _Function, typename _Type> auto _ReturnTypeHelper(_Type t, _Function _Func, ...)->_BadContinuationParamType;
+    // mutable functions
+    // ********************
+    // THREE ARGUMENTS:
 
-    template <typename _Function, typename _Type> auto _IsTaskHelper(_Type t, _Function _Func, int, int) -> decltype(_Func(_To_task(t)), std::true_type());
-    template <typename _Function, typename _Type> std::false_type _IsTaskHelper(_Type t, _Function _Func, int, ...);
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
 
-    template <typename _Function> auto _VoidReturnTypeHelper(_Function _Func, int, int) -> decltype(_Func(_To_task()));
-    template <typename _Function> auto _VoidReturnTypeHelper(_Function _Func, int, ...) -> decltype(_Func());
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
 
-    template <typename _Function> auto _VoidIsTaskHelper(_Function _Func, int, int) -> decltype(_Func(_To_task()), std::true_type());
-    template <typename _Function> std::false_type _VoidIsTaskHelper(_Function _Func, int, ...);
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg3 _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
 
-    template<typename _Function, typename _ExpectedParameterType>
-    struct _FunctionTypeTraits
-    {
-        typedef decltype(_ReturnTypeHelper(std::declval<_ExpectedParameterType>(), std::declval<_Function>(), 0, 0)) _FuncRetType;
-        static_assert(!std::is_same<_FuncRetType, _BadContinuationParamType>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)");
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
 
-        typedef decltype(_IsTaskHelper(std::declval<_ExpectedParameterType>(), std::declval<_Function>(), 0, 0)) _Takes_task;
-    };
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
 
-    template<typename _Function>
-    struct _FunctionTypeTraits<_Function, void>
-    {
-        typedef decltype(_VoidReturnTypeHelper(std::declval<_Function>(), 0, 0)) _FuncRetType;
-        typedef decltype(_VoidIsTaskHelper(std::declval<_Function>(), 0, 0)) _Takes_task;
-    };
+    // ********************
+    // TWO ARGUMENTS:
 
-    template<typename _Function, typename _ReturnType>
-    struct _ContinuationTypeTraits
-    {
-        typedef typename task<typename _TaskTypeTraits<typename _FunctionTypeTraits<_Function, _ReturnType>::_FuncRetType>::_TaskRetType> _TaskOfType;
-    };
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
 
-    // _InitFunctorTypeTraits is used to decide whether a task constructed with a lambda should be unwrapped. Depending on how the variable is
-    // declared, the constructor may or may not perform unwrapping. For eg.
-    //
-    //  This declaration SHOULD NOT cause unwrapping
-    //    task<task<void>> t1([]() -> task<void> {
-    //        task<void> t2([]() {});
-    //        return t2;
-    //    });
-    //
-    // This declaration SHOULD cause unwrapping
-    //    task<void>> t1([]() -> task<void> {
-    //        task<void> t2([]() {});
-    //        return t2;
-    //    });
-    // If the type of the task is the same as the return type of the function, no unwrapping should take place. Else normal rules apply.
-    template <typename _TaskType, typename _FuncRetType>
-    struct _InitFunctorTypeTraits
-    {
-        typedef typename _TaskTypeTraits<_FuncRetType>::_AsyncKind _AsyncKind;
-        static const bool _IsAsyncTask = _TaskTypeTraits<_FuncRetType>::_IsAsyncTask;
-        static const bool _IsUnwrappedTaskOrAsync = _TaskTypeTraits<_FuncRetType>::_IsUnwrappedTaskOrAsync;
-    };
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
 
-    template<typename T>
-    struct _InitFunctorTypeTraits<T, T>
-    {
-        typedef _TypeSelectorNoAsync _AsyncKind;
-        static const bool _IsAsyncTask = false;
-        static const bool _IsUnwrappedTaskOrAsync = false;
-    };
-    /// <summary>
-    ///     Helper object used for LWT invocation.
-    /// </summary>
-    struct _TaskProcThunk
-    {
-        _TaskProcThunk(const std::function<void()> & _Callback) :
-        _M_func(_Callback)
-        {
-        }
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
 
-        static void _Bridge(void *_PData)
-        {
-            _TaskProcThunk *_PThunk = reinterpret_cast<_TaskProcThunk *>(_PData);
-            _PThunk->_M_func();
-            delete _PThunk;
-        }
-    private:
-        std::function<void()> _M_func;
-        _TaskProcThunk& operator=(const _TaskProcThunk&);
-    };
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
 
-    /// <summary>
-    ///     Schedule a functor with automatic inlining. Note that this is "fire and forget" scheduling, which cannot be
-    ///     waited on or canceled after scheduling.
-    ///     This schedule method will perform automatic inlining base on <paramref value="_InliningMode"/>.
-    /// </summary>
-    /// <param name="_Func">
-    ///     The user functor need to be scheduled.
-    /// </param>
-    /// <param name="_InliningMode">
-    ///     The inlining scheduling policy for current functor.
-    /// </param>
-    static void _ScheduleFuncWithAutoInline(const std::function<void()> & _Func, Concurrency::details::_TaskInliningMode _InliningMode)
-    {
-        Concurrency::details::_StackGuard _Guard;
-        if (_Guard._ShouldInline(_InliningMode))
-        {
-            _Func();
-        }
-        else
-        {
-            Concurrency::details::_CurrentScheduler::_ScheduleTask(reinterpret_cast<Concurrency::TaskProc>(&_TaskProcThunk::_Bridge), new _TaskProcThunk(_Func));
-        }
-    }
-    class _ContextCallback
-    {
-        typedef std::function<HRESULT(void)> _CallbackFunction;
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2));
 
-    public:
+    // ********************
+    // ONE ARGUMENT:
 
-        static _ContextCallback _CaptureCurrent()
-        {
-            _ContextCallback _Context;
-            _Context._Capture();
-            return _Context;
-        }
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
 
-        ~_ContextCallback()
-        {
-            _Reset();
-        }
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    void _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
 
-        _ContextCallback(bool _DeferCapture = false)
-        {
-            if (_DeferCapture)
-            {
-                _M_context._M_captureMethod = _S_captureDeferred;
-            }
-            else
-            {
-                _M_context._M_pContextCallback = nullptr;
-            }
-        }
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
 
-        // Resolves a context that was created as _S_captureDeferred based on the environment (ancestor, current context).
-        void _Resolve(bool _CaptureCurrent)
-        {
-            if (_M_context._M_captureMethod == _S_captureDeferred)
-            {
-                _M_context._M_pContextCallback = nullptr;
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
 
-                if (_CaptureCurrent)
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1));
+
+    // ********************
+    // ZERO ARGUMENT:
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    void _Arg1ClassHelperThunk(_ReturnType(_Class::*)());
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    void _Arg2ClassHelperThunk(_ReturnType(_Class::*)());
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)());
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)());
+
+    template<typename _Class, typename _ReturnType>
+    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)());
+
+    // ********************
+    // THREE ARGUMENTS:
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg3 _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
+
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
+
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
+
+    // ********************
+    // TWO ARGUMENTS:
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
+
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
+
+    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
+    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
+
+    // ********************
+    // ONE ARGUMENT:
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    void _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
+
+    // non-void arg:
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
+
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
+
+    template<typename _Class, typename _ReturnType, typename _Arg1>
+    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1) const);
+
+    // ********************
+    // ZERO ARGUMENT:
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    void _Arg1ClassHelperThunk(_ReturnType(_Class::*)() const);
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    void _Arg2ClassHelperThunk(_ReturnType(_Class::*)() const);
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)() const);
+
+    // void arg:
+    template<typename _Class, typename _ReturnType>
+    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)() const);
+
+    template<typename _Class, typename _ReturnType>
+    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)() const);
+
+    // ****************************************
+    // POINTER TYPES:
+
+    // ********************
+    // THREE ARGUMENTS:
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg3 _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg3 _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _Arg3 _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
+    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+
+    // ********************
+    // TWO ARGUMENTS:
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+
+    template<typename _ReturnType, typename _Arg1, typename _Arg2>
+    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+
+    // ********************
+    // ONE ARGUMENT:
+
+    template<typename _ReturnType, typename _Arg1>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+
+    template<typename _ReturnType, typename _Arg1>
+    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1));
+
+    // ********************
+    // ZERO ARGUMENT:
+
+    template<typename _ReturnType>
+    void _Arg1PFNHelperThunk(_ReturnType(__cdecl *)());
+
+    template<typename _ReturnType>
+    void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)());
+
+    template<typename _ReturnType>
+    void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)());
+
+    template<typename _ReturnType>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)());
+
+    template<typename _ReturnType>
+    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)());
+
+    template<typename _ReturnType>
+    void _Arg1PFNHelperThunk(_ReturnType(__stdcall *)());
+
+    template<typename _ReturnType>
+    void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)());
+
+    template<typename _ReturnType>
+    void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)());
+
+    template<typename _ReturnType>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)());
+
+    template<typename _ReturnType>
+    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)());
+
+    template<typename _ReturnType>
+    void _Arg1PFNHelperThunk(_ReturnType(__fastcall *)());
+
+    template<typename _ReturnType>
+    void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)());
+
+    template<typename _ReturnType>
+    void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)());
+
+    template<typename _ReturnType>
+    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)());
+
+    template<typename _ReturnType>
+    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)());
+
+    template<typename _T>
+    struct _FunctorArguments
+    {
+        static const size_t _Count = 0;
+    };
+
+    template<>
+    struct _FunctorArguments<_OneArgumentFunctor>
+    {
+        static const size_t _Count = 1;
+    };
+
+    template<>
+    struct _FunctorArguments<_TwoArgumentFunctor>
+    {
+        static const size_t _Count = 2;
+    };
+
+    template<>
+    struct _FunctorArguments<_ThreeArgumentFunctor>
+    {
+        static const size_t _Count = 3;
+    };
+
+    template<typename _T>
+    struct _FunctorTypeTraits
+    {
+        typedef decltype(_ArgumentCountHelper(&(_T::operator()))) _ArgumentCountType;
+        static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count;
+
+        typedef decltype(_ReturnTypeClassHelperThunk(&(_T::operator()))) _ReturnType;
+        typedef decltype(_Arg1ClassHelperThunk(&(_T::operator()))) _Argument1Type;
+        typedef decltype(_Arg2ClassHelperThunk(&(_T::operator()))) _Argument2Type;
+        typedef decltype(_Arg3ClassHelperThunk(&(_T::operator()))) _Argument3Type;
+    };
+
+    template<typename _T>
+    struct _FunctorTypeTraits<_T *>
+    {
+        typedef decltype(_ArgumentCountHelper(stdx::declval<_T*>())) _ArgumentCountType;
+        static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count;
+
+        typedef decltype(_ReturnTypePFNHelperThunk(stdx::declval<_T*>())) _ReturnType;
+        typedef decltype(_Arg1PFNHelperThunk(stdx::declval<_T*>())) _Argument1Type;
+        typedef decltype(_Arg2PFNHelperThunk(stdx::declval<_T*>())) _Argument2Type;
+        typedef decltype(_Arg3PFNHelperThunk(stdx::declval<_T*>())) _Argument3Type;
+    };
+
+    task<void> _To_task();
+
+    template <typename _Function> auto _IsVoidConversionHelper(_Function _Func, int) -> typename decltype(_Func(_To_task()), std::true_type());
+    template <typename _Function> std::false_type _IsVoidConversionHelper(_Function _Func, ...);
+
+    template <typename T> std::true_type _VoidIsTaskHelper(task<T> _Arg, int);
+    template <typename T> std::false_type _VoidIsTaskHelper(T _Arg, ...);
+
+    template<typename _Function, typename _ExpectedParameterType, const bool _IsVoidConversion = std::is_same<decltype(_IsVoidConversionHelper(stdx::declval<_Function>(), 0)), std::true_type>::value, const size_t _Count = _FunctorTypeTraits<_Function>::_ArgumentCount>
+    struct _FunctionTypeTraits
+    {
+        typedef typename _Unhat<typename _FunctorTypeTraits<_Function>::_Argument2Type>::_Value _FuncRetType;
+        static_assert(std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, _ExpectedParameterType>::value ||
+                    std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, task<_ExpectedParameterType>>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)");
+
+        typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task;
+    };
+
+    //if there is a continuation parameter, then must use void/no return value
+    template<typename _Function, typename _ExpectedParameterType, const bool _IsVoidConversion>
+    struct _FunctionTypeTraits<_Function, _ExpectedParameterType, _IsVoidConversion, 1>
+    {
+        typedef void _FuncRetType;
+        static_assert(std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, _ExpectedParameterType>::value ||
+                    std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, task<_ExpectedParameterType>>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)");
+
+        typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task;
+    };
+
+    template<typename _Function>
+    struct _FunctionTypeTraits<_Function, void, true, 1>
+    {
+        typedef void _FuncRetType;
+        static_assert(std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, decltype(_To_task())>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)");
+
+        typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task;
+    };
+
+    template<typename _Function>
+    struct _FunctionTypeTraits<_Function, void, false, 1>
+    {
+        typedef typename _Unhat<typename _FunctorTypeTraits<_Function>::_Argument1Type>::_Value _FuncRetType;
+
+        typedef std::false_type _Takes_task;
+    };
+
+    template<typename _Function, typename _ExpectedParameterType, const bool _IsVoidConversion>
+    struct _FunctionTypeTraits<_Function, _ExpectedParameterType, _IsVoidConversion, 0>
+    {
+        typedef void _FuncRetType;
+
+        typedef std::false_type _Takes_task;
+    };
+
+    template<typename _Function, typename _ReturnType>
+    struct _ContinuationTypeTraits
+    {
+        typedef typename task<typename _TaskTypeTraits<typename _FunctionTypeTraits<_Function, _ReturnType>::_FuncRetType>::_TaskRetType_abi> _TaskOfType;
+    };
+
+    // _InitFunctorTypeTraits is used to decide whether a task constructed with a lambda should be unwrapped. Depending on how the variable is
+    // declared, the constructor may or may not perform unwrapping. For eg.
+    //
+    //  This declaration SHOULD NOT cause unwrapping
+    //    task<task<void>> t1([]() -> task<void> {
+    //        task<void> t2([]() {});
+    //        return t2;
+    //    });
+    //
+    // This declaration SHOULD cause unwrapping
+    //    task<void>> t1([]() -> task<void> {
+    //        task<void> t2([]() {});
+    //        return t2;
+    //    });
+    // If the type of the task is the same as the return type of the function, no unwrapping should take place. Else normal rules apply.
+    template <typename _TaskType, typename _FuncRetType>
+    struct _InitFunctorTypeTraits
+    {
+        typedef typename _TaskTypeTraits<_FuncRetType>::_AsyncKind _AsyncKind;
+        static const bool _IsAsyncTask = _TaskTypeTraits<_FuncRetType>::_IsAsyncTask;
+        static const bool _IsUnwrappedTaskOrAsync = _TaskTypeTraits<_FuncRetType>::_IsUnwrappedTaskOrAsync;
+    };
+
+    template<typename T>
+    struct _InitFunctorTypeTraits<T, T>
+    {
+        typedef _TypeSelectorNoAsync _AsyncKind;
+        static const bool _IsAsyncTask = false;
+        static const bool _IsUnwrappedTaskOrAsync = false;
+    };
+    /// <summary>
+    ///     Helper object used for LWT invocation.
+    /// </summary>
+    struct _TaskProcThunk
+    {
+        _TaskProcThunk(const std::function<HRESULT(void)> & _Callback) :
+        _M_func(_Callback)
+        {
+        }
+
+        static void __cdecl _Bridge(void *_PData)
+        {
+            _TaskProcThunk *_PThunk = reinterpret_cast<_TaskProcThunk *>(_PData);
+#if _MSC_VER >= 1800
+            _Holder _ThunkHolder(_PThunk);
+#endif
+            _PThunk->_M_func();
+#if _MSC_VER < 1800
+            delete _PThunk;
+#endif
+        }
+    private:
+#if _MSC_VER >= 1800
+        // RAII holder
+        struct _Holder
+        {
+            _Holder(_TaskProcThunk * _PThunk) : _M_pThunk(_PThunk)
+            {
+            }
+
+            ~_Holder()
+            {
+                delete _M_pThunk;
+            }
+
+            _TaskProcThunk * _M_pThunk;
+
+        private:
+            _Holder& operator=(const _Holder&);
+        };
+#endif
+        std::function<HRESULT(void)> _M_func;
+        _TaskProcThunk& operator=(const _TaskProcThunk&);
+    };
+
+    /// <summary>
+    ///     Schedule a functor with automatic inlining. Note that this is "fire and forget" scheduling, which cannot be
+    ///     waited on or canceled after scheduling.
+    ///     This schedule method will perform automatic inlining base on <paramref value="_InliningMode"/>.
+    /// </summary>
+    /// <param name="_Func">
+    ///     The user functor need to be scheduled.
+    /// </param>
+    /// <param name="_InliningMode">
+    ///     The inlining scheduling policy for current functor.
+    /// </param>
+#if _MSC_VER >= 1800
+    typedef Concurrency::details::_TaskInliningMode_t _TaskInliningMode;
+#else
+    typedef Concurrency::details::_TaskInliningMode _TaskInliningMode;
+#endif
+    static void _ScheduleFuncWithAutoInline(const std::function<HRESULT(void)> & _Func, _TaskInliningMode _InliningMode)
+    {
+#if _MSC_VER >= 1800
+        Concurrency::details::_TaskCollection_t::_RunTask(&_TaskProcThunk::_Bridge, new _TaskProcThunk(_Func), _InliningMode);
+#else
+        Concurrency::details::_StackGuard _Guard;
+        if (_Guard._ShouldInline(_InliningMode))
+        {
+            _Func();
+        }
+        else
+        {
+            Concurrency::details::_CurrentScheduler::_ScheduleTask(reinterpret_cast<Concurrency::TaskProc>(&_TaskProcThunk::_Bridge), new _TaskProcThunk(_Func));
+        }
+#endif
+    }
+    class _ContextCallback
+    {
+        typedef std::function<HRESULT(void)> _CallbackFunction;
+
+    public:
+
+        static _ContextCallback _CaptureCurrent()
+        {
+            _ContextCallback _Context;
+            _Context._Capture();
+            return _Context;
+        }
+
+        ~_ContextCallback()
+        {
+            _Reset();
+        }
+
+        _ContextCallback(bool _DeferCapture = false)
+        {
+            if (_DeferCapture)
+            {
+                _M_context._M_captureMethod = _S_captureDeferred;
+            }
+            else
+            {
+                _M_context._M_pContextCallback = nullptr;
+            }
+        }
+
+        // Resolves a context that was created as _S_captureDeferred based on the environment (ancestor, current context).
+        void _Resolve(bool _CaptureCurrent)
+        {
+            if (_M_context._M_captureMethod == _S_captureDeferred)
+            {
+                _M_context._M_pContextCallback = nullptr;
+
+                if (_CaptureCurrent)
                 {
                     if (_IsCurrentOriginSTA())
                     {
@@ -629,7 +1236,7 @@ namespace details
         }
 
         // Returns the origin information for the caller (runtime / Windows Runtime apartment as far as task continuations need know)
-        bool _IsCurrentOriginSTA()
+        static bool _IsCurrentOriginSTA()
         {
             APTTYPE _AptType;
             APTTYPEQUALIFIER _AptTypeQualifier;
@@ -655,351 +1262,108 @@ namespace details
 
         union
         {
-            IContextCallback *_M_pContextCallback;
-            size_t _M_captureMethod;
-        } _M_context;
-
-        static const size_t _S_captureDeferred = 1;
-    };
-
-    template<typename _Type>
-    struct _ResultContext
-    {
-        static _ContextCallback _GetContext(bool /* _RuntimeAggregate */)
-        {
-            return _ContextCallback();
-        }
-
-        static _Type _GetValue(_Type _ObjInCtx, const _ContextCallback & /* _Ctx */, bool /* _RuntimeAggregate */)
-        {
-            return _ObjInCtx;
-        }
-    };
-
-    template<typename _Type, bool bUnknown = __is_base_of(IUnknown, _Type)>
-    struct winrt_type
-    {
-    };
-    template<typename _Type>
-    struct winrt_type<_Type, true>
-    {
-        static IUnknown* create(_Type* _ObjInCtx) {
-            return reinterpret_cast<IUnknown*>(_ObjInCtx);
-        }
-        static IID getuuid() { return __uuidof(_Type); }
-    };
-    template <typename _Type>
-    struct winrt_type<_Type, false>
-    {
-        static IUnknown* create(_Type* _ObjInCtx) {
-            Microsoft::WRL::ComPtr<IInspectable> _PObj;
-            Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
-            HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
-            if (FAILED(hr)) return nullptr;
-            Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
-            if (SUCCEEDED(hr))
-                hr = objFactory.As(&spPropVal);
-            if (SUCCEEDED(hr)) {
-                hr = winrt_type<_Type>::create(spPropVal.Get(), _ObjInCtx, _PObj.GetAddressOf());
-                if (SUCCEEDED(hr))
-                    return reinterpret_cast<IUnknown*>(_PObj.Detach());
-            }
-            return nullptr;
-        }
-        static IID getuuid() { return __uuidof(ABI::Windows::Foundation::IPropertyValue); }
-    };
-
-    template<>
-    struct winrt_type<void>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, void* _ObjInCtx, IInspectable** ppInsp) {
-            (void)_ObjInCtx;
-            return spPropVal->CreateEmpty(ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<BYTE>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, BYTE* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt8(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<INT16>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, INT16* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInt16(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<UINT16>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT16* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt16(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<INT32>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, INT32* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInt32(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<UINT32>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt32(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<INT64>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, INT64* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInt64(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<UINT64>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT64* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt64(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<FLOAT>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, FLOAT* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateSingle(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<DOUBLE>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, DOUBLE* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateDouble(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<WCHAR>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, WCHAR* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateChar16(*_ObjInCtx, ppInsp);
-        }
-    };
-    //template<>
-    //struct winrt_type<boolean>
-    //{
-    //    static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, boolean* _ObjInCtx, IInspectable** ppInsp) {
-    //        return spPropVal->CreateBoolean(*_ObjInCtx, ppInsp);
-    //    }
-    //};
-    template<>
-    struct winrt_type<HSTRING>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, HSTRING* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateString(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<IInspectable*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, IInspectable** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInspectable(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<GUID>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, GUID* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateGuid(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<ABI::Windows::Foundation::DateTime>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, ABI::Windows::Foundation::DateTime* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateDateTime(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<ABI::Windows::Foundation::TimeSpan>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, ABI::Windows::Foundation::TimeSpan* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateTimeSpan(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<ABI::Windows::Foundation::Point>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, ABI::Windows::Foundation::Point* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreatePoint(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<ABI::Windows::Foundation::Size>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, ABI::Windows::Foundation::Size* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateSize(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_type<ABI::Windows::Foundation::Rect>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, ABI::Windows::Foundation::Rect* _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateRect(*_ObjInCtx, ppInsp);
-        }
-    };
-    template<typename _Type>
-    struct winrt_array_type
-    {
-        static IUnknown* create(_Type* _ObjInCtx, size_t N) {
-            Microsoft::WRL::ComPtr<IInspectable> _PObj;
-            Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
-            HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
-            if (FAILED(hr)) return nullptr;
-            Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
-            if (SUCCEEDED(hr))
-                hr = objFactory.As(&spPropVal);
-            if (SUCCEEDED(hr)) {
-                hr = winrt_array_type<_Type>::create(spPropVal.Get(), N, _ObjInCtx, _PObj.GetAddressOf());
-                if (SUCCEEDED(hr))
-                    return reinterpret_cast<IUnknown*>(_PObj.Detach());
-            }
-            return nullptr;
-        }
-    };
-    template<>
-    struct winrt_array_type<BYTE*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, BYTE** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt8Array(__valueSize, *_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_array_type<INT16*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, INT16** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInt16Array(__valueSize, *_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_array_type<UINT16*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, UINT16** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt16Array(__valueSize, *_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_array_type<INT32*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, INT32** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInt32Array(__valueSize, *_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_array_type<UINT32*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, UINT32** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt32Array(__valueSize, *_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_array_type<INT64*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, INT64** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInt64Array(__valueSize, *_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_array_type<UINT64*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, UINT64** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateUInt64Array(__valueSize, *_ObjInCtx, ppInsp);
-        }
-    };
-    template<>
-    struct winrt_array_type<FLOAT*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, FLOAT** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateSingleArray(__valueSize, *_ObjInCtx, ppInsp);
-        }
+            IContextCallback *_M_pContextCallback;
+            size_t _M_captureMethod;
+        } _M_context;
+
+        static const size_t _S_captureDeferred = 1;
     };
-    template<>
-    struct winrt_array_type<DOUBLE*>
+
+#if _MSC_VER >= 1800
+    template<typename _Type>
+    struct _ResultHolder
     {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, DOUBLE** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateDoubleArray(__valueSize, *_ObjInCtx, ppInsp);
+        void Set(const _Type& _type)
+        {
+            _Result = _type;
         }
-    };
-    template<>
-    struct winrt_array_type<WCHAR*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, WCHAR** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateChar16Array(__valueSize, *_ObjInCtx, ppInsp);
+
+        _Type Get()
+        {
+            return _Result;
         }
+
+        _Type _Result;
     };
-    //template<>
-    //struct winrt_array_type<boolean*>
-    //{
-    //    static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, boolean** _ObjInCtx, IInspectable** ppInsp) {
-    //        return spPropVal->CreateBooleanArray(__valueSize, *_ObjInCtx, ppInsp);
-    //    }
-    //};
-    template<>
-    struct winrt_array_type<HSTRING*>
+
+    template<typename _Type>
+    struct _ResultHolder<_Type*>
     {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, HSTRING** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateStringArray(__valueSize, *_ObjInCtx, ppInsp);
+        void Set(_Type* const & _type)
+        {
+            _M_Result = _type;
         }
-    };
-    template<>
-    struct winrt_array_type<IInspectable*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, IInspectable*** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateInspectableArray(__valueSize, *_ObjInCtx, ppInsp);
+
+        _Type* Get()
+        {
+            return _M_Result.Get();
         }
+    private:
+        // ::Platform::Agile handle specialization of all hats
+        // including ::Platform::String and ::Platform::Array
+        Agile<_Type*> _M_Result;
     };
-    template<>
-    struct winrt_array_type<GUID>
+
+    //
+    // The below are for composability with tasks auto-created from when_any / when_all / && / || constructs.
+    //
+    template<typename _Type>
+    struct _ResultHolder<std::vector<_Type*>>
     {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, GUID** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateGuidArray(__valueSize, *_ObjInCtx, ppInsp);
+        void Set(const std::vector<_Type*>& _type)
+        {
+            _Result.reserve(_type.size());
+
+            for (auto _PTask = _type.begin(); _PTask != _type.end(); ++_PTask)
+            {
+                _Result.emplace_back(*_PTask);
+            }
         }
-    };
-    template<>
-    struct winrt_array_type<ABI::Windows::Foundation::DateTime*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, ABI::Windows::Foundation::DateTime** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateDateTimeArray(__valueSize, *_ObjInCtx, ppInsp);
+
+        std::vector<_Type*> Get()
+        {
+            // Return vectory<T^> with the objects that are marshaled in the proper appartment
+            std::vector<_Type*> _Return;
+            _Return.reserve(_Result.size());
+
+            for (auto _PTask = _Result.begin(); _PTask != _Result.end(); ++_PTask)
+            {
+                _Return.push_back(_PTask->Get()); // Agile will marshal the object to appropriate appartment if neccessary
+            }
+
+            return _Return;
         }
+
+        std::vector< Agile<_Type*> > _Result;
     };
-    template<>
-    struct winrt_array_type<ABI::Windows::Foundation::TimeSpan*>
+
+    template<typename _Type>
+    struct _ResultHolder<std::pair<_Type*, void*> >
     {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, ABI::Windows::Foundation::TimeSpan** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateTimeSpanArray(__valueSize, *_ObjInCtx, ppInsp);
+        void Set(const std::pair<_Type*, size_t>& _type)
+        {
+            _M_Result = _type;
         }
-    };
-    template<>
-    struct winrt_array_type<ABI::Windows::Foundation::Point*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, ABI::Windows::Foundation::Point** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreatePointArray(__valueSize, *_ObjInCtx, ppInsp);
+
+        std::pair<_Type*, size_t> Get()
+        {
+            return std::make_pair(_M_Result.first, _M_Result.second);
         }
+    private:
+        std::pair<Agile<_Type*>, size_t> _M_Result;
     };
-    template<>
-    struct winrt_array_type<ABI::Windows::Foundation::Size*>
+#else
+    template<typename _Type>
+    struct _ResultContext
     {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, ABI::Windows::Foundation::Size** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateSizeArray(__valueSize, *_ObjInCtx, ppInsp);
+        static _ContextCallback _GetContext(bool /* _RuntimeAggregate */)
+        {
+            return _ContextCallback();
         }
-    };
-    template<>
-    struct winrt_array_type<ABI::Windows::Foundation::Rect*>
-    {
-        static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, ABI::Windows::Foundation::Rect** _ObjInCtx, IInspectable** ppInsp) {
-            return spPropVal->CreateRectArray(__valueSize, *_ObjInCtx, ppInsp);
+
+        static _Type _GetValue(_Type _ObjInCtx, const _ContextCallback & /* _Ctx */, bool /* _RuntimeAggregate */)
+        {
+            return _ObjInCtx;
         }
     };
 
@@ -1049,7 +1413,7 @@ namespace details
     {
         static _Type* _Perform(_Type* _ObjInCtx, const _ContextCallback& _Ctx)
         {
-            static_assert(__is_base_of(IUnknown, _Type) || __is_valid_winrt_type(_Type), "must be a COM or WinRT type");
+            static_assert(std::is_base_of<IUnknown, _Type>::value || __is_valid_winrt_type(_Type), "must be a COM or WinRT type");
             if (_ObjInCtx == nullptr)
             {
                 return nullptr;
@@ -1082,7 +1446,16 @@ namespace details
         }
     };
 
-    // Strings and arrays must be converted to IPropertyValue objects.
+    // Arrays must be converted to IPropertyValue objects.
+
+    template<>
+    struct _MarshalHelper<HSTRING__>
+    {
+        static HSTRING _Perform(HSTRING _ObjInCtx, const _ContextCallback& _Ctx)
+        {
+            return _ObjInCtx;
+        }
+    };
 
     template<typename _Type>
     _Type* _Marshal(_Type* _ObjInCtx, const _ContextCallback& _Ctx)
@@ -1202,11 +1575,32 @@ namespace details
             }
         }
     };
+#endif
     // An exception thrown by the task body is captured in an exception holder and it is shared with all value based continuations rooted at the task.
     // The exception is 'observed' if the user invokes get()/wait() on any of the tasks that are sharing this exception holder. If the exception
     // is not observed by the time the internal object owned by the shared pointer destructs, the process will fail fast.
     struct _ExceptionHolder
     {
+#if _MSC_VER >= 1800
+    private:
+        void ReportUnhandledError()
+        {
+            if (_M_winRTException != nullptr)
+            {
+                throw _M_winRTException.Get();
+            }
+        }
+    public:
+        explicit _ExceptionHolder(const std::exception_ptr& _E, const _TaskCreationCallstack &_stackTrace) :
+            _M_exceptionObserved(0), _M_stdException(_E), _M_stackTrace(_stackTrace)
+        {
+        }
+
+        explicit _ExceptionHolder(IRestrictedErrorInfo*& _E, const _TaskCreationCallstack &_stackTrace) :
+            _M_exceptionObserved(0), _M_winRTException(_E), _M_stackTrace(_stackTrace)
+        {
+        }
+#else
         explicit _ExceptionHolder(const std::exception_ptr& _E, void* _SourceAddressHint) :
         _M_exceptionObserved(0), _M_stdException(_E), _M_disassembleMe(_SourceAddressHint)
         {
@@ -1216,14 +1610,22 @@ namespace details
             _M_exceptionObserved(0), _M_disassembleMe(_SourceAddressHint), _M_winRTException(_E)
         {
         }
+#endif
         __declspec(noinline)
             ~_ExceptionHolder()
         {
             if (_M_exceptionObserved == 0)
             {
+#if _MSC_VER >= 1800
+                // If you are trapped here, it means an exception thrown in task chain didn't get handled.
+                // Please add task-based continuation to handle all exceptions coming from tasks.
+                // this->_M_stackTrace keeps the creation callstack of the task generates this exception.
+                _REPORT_PPLTASK_UNOBSERVED_EXCEPTION();
+#else
                 // Disassemble at this->_M_disassembleMe to get to the source location right after either the creation of the task (constructor
                 // or then method) that encountered this exception, or the set_exception call for a task_completion_event.
                 Concurrency::details::_ReportUnobservedException();
+#endif
             }
         }
 
@@ -1231,7 +1633,11 @@ namespace details
         {
             if (_M_exceptionObserved == 0)
             {
+#if _MSC_VER >= 1800
+                Concurrency::details::atomic_exchange(_M_exceptionObserved, 1l);
+#else
                 _InterlockedExchange(&_M_exceptionObserved, 1);
+#endif
             }
 
             if (_M_winRTException != nullptr)
@@ -1243,7 +1649,11 @@ namespace details
 
         // A variable that remembers if this exception was every rethrown into user code (and hence handled by the user). Exceptions that
         // are unobserved when the exception holder is destructed will terminate the process.
+#if _MSC_VER >= 1800
+        Concurrency::details::atomic_long _M_exceptionObserved;
+#else
         long volatile _M_exceptionObserved;
+#endif
 
         // Either _M_stdException or _M_winRTException is populated based on the type of exception encountered.
         std::exception_ptr _M_stdException;
@@ -1253,67 +1663,82 @@ namespace details
         // a task constructor or the then method, the task created by that method is the one that encountered this exception. If the call
         // is to task_completion_event::set_exception, the set_exception method was the source of the exception.
         // DO NOT REMOVE THIS VARIABLE. It is extremely helpful for debugging.
+#if _MSC_VER >= 1800
+        _TaskCreationCallstack _M_stackTrace;
+#else
         void* _M_disassembleMe;
+#endif
     };
 
-    template<typename _AsyncOperationType, typename _CompletionHandlerType, typename _Function>
-    struct _AsyncInfoCompletionHandler : public Microsoft::WRL::RuntimeClass<
-        Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::ClassicCom>, _CompletionHandlerType>
-    {
-        MixInHelper()
-    public:
-        _AsyncInfoCompletionHandler(_Function func) : _M_function(func) {}
-        STDMETHODIMP Invoke(_AsyncOperationType *asyncInfo, ABI::Windows::Foundation::AsyncStatus status)
-        {
-            return _M_function(asyncInfo, status);
-        }
-    protected:
-        _Function _M_function;
-    };
+#ifndef RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoImpl_DEFINED
+#define RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoImpl_DEFINED
+    extern const __declspec(selectany) WCHAR RuntimeClass_Concurrency_winrt_details__AsyncInfoImpl[] = L"Concurrency_winrt.details._AsyncInfoImpl";
+#endif
 
-    template<typename _AsyncOperationType, typename _CompletionHandlerType, typename _Function>
-    __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
-        _AsyncInfoCompletionHandler<_AsyncOperationType, _CompletionHandlerType, _Function>* create_completionhandler(const _Function& _Func)
-    {
-        return Microsoft::WRL::Make<_AsyncInfoCompletionHandler<_AsyncOperationType, _CompletionHandlerType, _Function>>(_Func).Detach();
-    }
     /// <summary>
     ///     Base converter class for converting asynchronous interfaces to IAsyncOperation
     /// </summary>
-    template<typename _AsyncOperationType, typename _CompletionHandlerType, typename _Result>
+    template<typename _AsyncOperationType, typename _CompletionHandlerType, typename _Result_abi>
     struct _AsyncInfoImpl abstract : public Microsoft::WRL::RuntimeClass<
         Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>,
-        Microsoft::WRL::Implements<ABI::Windows::Foundation::IAsyncOperation<_Result>, Microsoft::WRL::AsyncBase<_CompletionHandlerType>>>
+        Microsoft::WRL::Implements<Microsoft::WRL::AsyncBase<_CompletionHandlerType>>>
     {
+        InspectableClass(RuntimeClass_Concurrency_winrt_details__AsyncInfoImpl, BaseTrust)
     public:
         // The async action, action with progress or operation with progress that this stub forwards to.
+#if _MSC_VER >= 1800
+        Agile<_AsyncOperationType> _M_asyncInfo;
+#else
         Microsoft::WRL::ComPtr<_AsyncOperationType> _M_asyncInfo;
         // The context in which this async info is valid - may be different from the context where the completion handler runs,
         // and may require marshalling before it is used.
         _ContextCallback _M_asyncInfoContext;
+#endif
 
-        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>> _M_CompletedHandler;
+        Microsoft::WRL::ComPtr<_CompletionHandlerType> _M_CompletedHandler;
 
-        _AsyncInfoImpl(_AsyncOperationType* _AsyncInfo) : _M_asyncInfo(_AsyncInfo), _M_asyncInfoContext(_ContextCallback::_CaptureCurrent()) {}
+        _AsyncInfoImpl(_AsyncOperationType* _AsyncInfo) : _M_asyncInfo(_AsyncInfo)
+#if _MSC_VER < 1800
+            , _M_asyncInfoContext(_ContextCallback::_CaptureCurrent())
+#endif
+        {}
 
     public:
         virtual HRESULT OnStart() { return S_OK; }
         virtual void OnCancel() {
             Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
-            if (SUCCEEDED(_M_asyncInfo.As(&pAsyncInfo)))
+            HRESULT hr;
+#if _MSC_VER >= 1800
+            if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
+#else
+            if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
+#endif
                 pAsyncInfo->Cancel();
+            else
+                throw std::make_exception_ptr(hr);
         }
         virtual void OnClose() {
             Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
-            if (SUCCEEDED(_M_asyncInfo.As(&pAsyncInfo)))
+            HRESULT hr;
+#if _MSC_VER >= 1800
+            if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
+#else
+            if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
+#endif
                 pAsyncInfo->Close();
+            else
+                throw std::make_exception_ptr(hr);
         }
 
         virtual STDMETHODIMP get_ErrorCode(HRESULT* errorCode)
         {
             Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
             HRESULT hr;
+#if _MSC_VER >= 1800
+            if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
+#else
             if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
+#endif
                 return pAsyncInfo->get_ErrorCode(errorCode);
             return hr;
         }
@@ -1322,7 +1747,11 @@ namespace details
         {
             Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
             HRESULT hr;
+#if _MSC_VER >= 1800
+            if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
+#else
             if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
+#endif
                 return pAsyncInfo->get_Id(id);
             return hr;
         }
@@ -1331,31 +1760,72 @@ namespace details
         {
             Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
             HRESULT hr;
+#if _MSC_VER >= 1800
+            if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
+#else
             if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
+#endif
                 return pAsyncInfo->get_Status(status);
             return hr;
         }
 
-        virtual STDMETHODIMP GetResults(_Result*) { throw std::runtime_error("derived class must implement"); }
+        virtual STDMETHODIMP GetResults(_Result_abi*) { throw std::runtime_error("derived class must implement"); }
 
-        virtual STDMETHODIMP get_Completed(ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>** handler)
+        virtual STDMETHODIMP get_Completed(_CompletionHandlerType** handler)
         {
             if (!handler) return E_POINTER;
             _M_CompletedHandler.CopyTo(handler);
             return S_OK;
         }
 
-        virtual    STDMETHODIMP put_Completed(ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>* value)
+        virtual    STDMETHODIMP put_Completed(_CompletionHandlerType* value)
         {
             _M_CompletedHandler = value;
-            return _M_asyncInfo->put_Completed(create_completionhandler<_AsyncOperationType, _CompletionHandlerType>([&](_AsyncOperationType*, ABI::Windows::Foundation::AsyncStatus status) -> HRESULT {
+            Microsoft::WRL::ComPtr<_CompletionHandlerType> handler = Microsoft::WRL::Callback<_CompletionHandlerType>([&](_AsyncOperationType*, ABI::Windows::Foundation::AsyncStatus status) -> HRESULT {
+#if _MSC_VER < 1800
                 // Update the saved _M_asyncInfo with a proxy valid in the current context if required. Some Windows APIs return an IAsyncInfo
                 // that is only valid for the thread that called the API to retrieve. Since this completion handler can run on any thread, we
                 // need to ensure that the async info is valid in the current apartment. _M_asyncInfo will be accessed via calls to 'this' inside
                 // _AsyncInit.
                 _M_asyncInfo = _ResultContext<_AsyncOperationType*>::_GetValue(_M_asyncInfo.Get(), _M_asyncInfoContext, false);
-                return _M_CompletedHandler->Invoke(this, status);
-            }));
+#endif
+                return _M_CompletedHandler->Invoke(_M_asyncInfo.Get(), status);
+            });
+#if _MSC_VER >= 1800
+            return _M_asyncInfo.Get()->put_Completed(handler.Get());
+#else
+            return _M_asyncInfo->put_Completed(handler.Get());
+#endif
+        }
+    };
+
+    extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncOperationToAsyncOperationConverter[] = L"_IAsyncOperationToAsyncOperationConverter";
+
+    /// <summary>
+    ///     Class _IAsyncOperationToAsyncOperationConverter is used to convert an instance of IAsyncOperationWithProgress<T> into IAsyncOperation<T>
+    /// </summary>
+    template<typename _Result>
+    struct _IAsyncOperationToAsyncOperationConverter :
+        _AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperation<_Result>,
+        ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>,
+        typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_Result>*>()))>::type>
+    {
+        typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_Result>*>()))>::type _Result_abi;
+
+        InspectableClass(RuntimeClass_IAsyncOperationToAsyncOperationConverter, BaseTrust)
+    public:
+        _IAsyncOperationToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncOperation<_Result>* _Operation) :
+            _AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperation<_Result>,
+            ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>,
+            _Result_abi>(_Operation) {}
+    public:
+        virtual STDMETHODIMP GetResults(_Result_abi* results) override {
+            if (!results) return E_POINTER;
+#if _MSC_VER >= 1800
+            return _M_asyncInfo.Get()->GetResults(results);
+#else
+            return _M_asyncInfo->GetResults(results);
+#endif
         }
     };
 
@@ -1365,21 +1835,27 @@ namespace details
     ///     Class _IAsyncOperationWithProgressToAsyncOperationConverter is used to convert an instance of IAsyncOperationWithProgress<T> into IAsyncOperation<T>
     /// </summary>
     template<typename _Result, typename _Progress>
-    struct _IAsyncOperationWithProgressToAsyncOperationConverter sealed :
+    struct _IAsyncOperationWithProgressToAsyncOperationConverter :
     _AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>,
         ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_Result, _Progress>,
-        _Result>
+        typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>*>()))>::type>
     {
+        typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>*>()))>::type _Result_abi;
+
         InspectableClass(RuntimeClass_IAsyncOperationWithProgressToAsyncOperationConverter, BaseTrust)
     public:
         _IAsyncOperationWithProgressToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>* _Operation) :
             _AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>,
             ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_Result, _Progress>,
-            _Result>(_Operation) {}
+            _Result_abi>(_Operation) {}
     public:
-        virtual STDMETHODIMP GetResults(_Result* results) override {
+        virtual STDMETHODIMP GetResults(_Result_abi* results) override {
             if (!results) return E_POINTER;
+#if _MSC_VER >= 1800
+            return _M_asyncInfo.Get()->GetResults(results);
+#else
             return _M_asyncInfo->GetResults(results);
+#endif
         }
     };
 
@@ -1388,7 +1864,7 @@ namespace details
     /// <summary>
     ///     Class _IAsyncActionToAsyncOperationConverter is used to convert an instance of IAsyncAction into IAsyncOperation<_Unit_type>
     /// </summary>
-    struct _IAsyncActionToAsyncOperationConverter sealed :
+    struct _IAsyncActionToAsyncOperationConverter :
     _AsyncInfoImpl<ABI::Windows::Foundation::IAsyncAction,
         ABI::Windows::Foundation::IAsyncActionCompletedHandler,
         _Unit_type>
@@ -1405,7 +1881,11 @@ namespace details
         {
             if (!results) return E_POINTER;
             // Invoke GetResults on the IAsyncAction to allow exceptions to be thrown to higher layers before returning a dummy value.
+#if _MSC_VER >= 1800
+            HRESULT hr = _M_asyncInfo.Get()->GetResults();
+#else
             HRESULT hr = _M_asyncInfo->GetResults();
+#endif
             if (SUCCEEDED(hr)) *results = _Unit_type();
             return hr;
         }
@@ -1417,7 +1897,7 @@ namespace details
     ///     Class _IAsyncActionWithProgressToAsyncOperationConverter is used to convert an instance of IAsyncActionWithProgress into IAsyncOperation<_Unit_type>
     /// </summary>
     template<typename _Progress>
-    struct _IAsyncActionWithProgressToAsyncOperationConverter sealed :
+    struct _IAsyncActionWithProgressToAsyncOperationConverter :
     _AsyncInfoImpl<ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>,
         ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_Progress>,
         _Unit_type>
@@ -1431,9 +1911,13 @@ namespace details
     public:
         virtual STDMETHODIMP GetResults(_Unit_type* results) override
         {
-            if (!result) return E_POINTER;
+            if (!results) return E_POINTER;
             // Invoke GetResults on the IAsyncActionWithProgress to allow exceptions to be thrown before returning a dummy value.
+#if _MSC_VER >= 1800
+            HRESULT hr = _M_asyncInfo.Get()->GetResults();
+#else
             HRESULT hr = _M_asyncInfo->GetResults();
+#endif
             if (SUCCEEDED(hr)) *results = _Unit_type();
             return hr;
         }
@@ -1523,28 +2007,253 @@ private:
     }
 };
 
+#if _MSC_VER >= 1800
+class task_options;
+namespace details
+{
+    struct _Internal_task_options
+    {
+        bool _M_hasPresetCreationCallstack;
+        _TaskCreationCallstack _M_presetCreationCallstack;
+
+        void _set_creation_callstack(const _TaskCreationCallstack &_callstack)
+        {
+            _M_hasPresetCreationCallstack = true;
+            _M_presetCreationCallstack = _callstack;
+        }
+        _Internal_task_options()
+        {
+            _M_hasPresetCreationCallstack = false;
+        }
+    };
+
+    inline _Internal_task_options &_get_internal_task_options(task_options &options);
+    inline const _Internal_task_options &_get_internal_task_options(const task_options &options);
+}
+/// <summary>
+///     Represents the allowed options for creating a task
+/// </summary>
+class task_options
+{
+public:
+
+
+    /// <summary>
+    ///     Default list of task creation options
+    /// </summary>
+    task_options()
+        : _M_Scheduler(Concurrency::get_ambient_scheduler()),
+        _M_CancellationToken(Concurrency::cancellation_token::none()),
+        _M_ContinuationContext(task_continuation_context::use_default()),
+        _M_HasCancellationToken(false),
+        _M_HasScheduler(false)
+    {
+    }
+
+    /// <summary>
+    ///     Task option that specify a cancellation token
+    /// </summary>
+    task_options(Concurrency::cancellation_token _Token)
+        : _M_Scheduler(Concurrency::get_ambient_scheduler()),
+        _M_CancellationToken(_Token),
+        _M_ContinuationContext(task_continuation_context::use_default()),
+        _M_HasCancellationToken(true),
+        _M_HasScheduler(false)
+    {
+    }
+
+    /// <summary>
+    ///     Task option that specify a continuation context. This is valid only for continuations (then)
+    /// </summary>
+    task_options(task_continuation_context _ContinuationContext)
+        : _M_Scheduler(Concurrency::get_ambient_scheduler()),
+        _M_CancellationToken(Concurrency::cancellation_token::none()),
+        _M_ContinuationContext(_ContinuationContext),
+        _M_HasCancellationToken(false),
+        _M_HasScheduler(false)
+    {
+    }
+
+    /// <summary>
+    ///     Task option that specify a cancellation token and a continuation context. This is valid only for continuations (then)
+    /// </summary>
+    task_options(Concurrency::cancellation_token _Token, task_continuation_context _ContinuationContext)
+        : _M_Scheduler(Concurrency::get_ambient_scheduler()),
+        _M_CancellationToken(_Token),
+        _M_ContinuationContext(_ContinuationContext),
+        _M_HasCancellationToken(false),
+        _M_HasScheduler(false)
+    {
+    }
+
+    /// <summary>
+    ///     Task option that specify a scheduler with shared lifetime
+    /// </summary>
+    template<typename _SchedType>
+    task_options(std::shared_ptr<_SchedType> _Scheduler)
+        : _M_Scheduler(std::move(_Scheduler)),
+        _M_CancellationToken(cancellation_token::none()),
+        _M_ContinuationContext(task_continuation_context::use_default()),
+        _M_HasCancellationToken(false),
+        _M_HasScheduler(true)
+    {
+    }
+
+    /// <summary>
+    ///     Task option that specify a scheduler reference
+    /// </summary>
+    task_options(Concurrency::scheduler_interface& _Scheduler)
+        : _M_Scheduler(&_Scheduler),
+        _M_CancellationToken(Concurrency::cancellation_token::none()),
+        _M_ContinuationContext(task_continuation_context::use_default()),
+        _M_HasCancellationToken(false),
+        _M_HasScheduler(true)
+    {
+    }
+
+    /// <summary>
+    ///     Task option that specify a scheduler
+    /// </summary>
+    task_options(Concurrency::scheduler_ptr _Scheduler)
+        : _M_Scheduler(std::move(_Scheduler)),
+        _M_CancellationToken(Concurrency::cancellation_token::none()),
+        _M_ContinuationContext(task_continuation_context::use_default()),
+        _M_HasCancellationToken(false),
+        _M_HasScheduler(true)
+    {
+    }
+
+    /// <summary>
+    ///     Task option copy constructor
+    /// </summary>
+    task_options(const task_options& _TaskOptions)
+        : _M_Scheduler(_TaskOptions.get_scheduler()),
+        _M_CancellationToken(_TaskOptions.get_cancellation_token()),
+        _M_ContinuationContext(_TaskOptions.get_continuation_context()),
+        _M_HasCancellationToken(_TaskOptions.has_cancellation_token()),
+        _M_HasScheduler(_TaskOptions.has_scheduler())
+    {
+    }
+
+    /// <summary>
+    ///     Sets the given token in the options
+    /// </summary>
+    void set_cancellation_token(Concurrency::cancellation_token _Token)
+    {
+        _M_CancellationToken = _Token;
+        _M_HasCancellationToken = true;
+    }
+
+    /// <summary>
+    ///     Sets the given continuation context in the options
+    /// </summary>
+    void set_continuation_context(task_continuation_context _ContinuationContext)
+    {
+        _M_ContinuationContext = _ContinuationContext;
+    }
+
+    /// <summary>
+    ///     Indicates whether a cancellation token was specified by the user
+    /// </summary>
+    bool has_cancellation_token() const
+    {
+        return _M_HasCancellationToken;
+    }
+
+    /// <summary>
+    ///     Returns the cancellation token
+    /// </summary>
+    Concurrency::cancellation_token get_cancellation_token() const
+    {
+        return _M_CancellationToken;
+    }
+
+    /// <summary>
+    ///     Returns the continuation context
+    /// </summary>
+    task_continuation_context get_continuation_context() const
+    {
+        return _M_ContinuationContext;
+    }
+
+    /// <summary>
+    ///     Indicates whether a scheduler n was specified by the user
+    /// </summary>
+    bool has_scheduler() const
+    {
+        return _M_HasScheduler;
+    }
+
+    /// <summary>
+    ///     Returns the scheduler
+    /// </summary>
+    Concurrency::scheduler_ptr get_scheduler() const
+    {
+        return _M_Scheduler;
+    }
+
+private:
+
+    task_options const& operator=(task_options const& _Right);
+    friend details::_Internal_task_options &details::_get_internal_task_options(task_options &);
+    friend const details::_Internal_task_options &details::_get_internal_task_options(const task_options &);
+
+    Concurrency::scheduler_ptr _M_Scheduler;
+    Concurrency::cancellation_token _M_CancellationToken;
+    task_continuation_context _M_ContinuationContext;
+    details::_Internal_task_options _M_InternalTaskOptions;
+    bool _M_HasCancellationToken;
+    bool _M_HasScheduler;
+};
+#endif
+
 namespace details
 {
+#if _MSC_VER >= 1800
+    inline _Internal_task_options & _get_internal_task_options(task_options &options)
+    {
+        return options._M_InternalTaskOptions;
+    }
+    inline const _Internal_task_options & _get_internal_task_options(const task_options &options)
+    {
+        return options._M_InternalTaskOptions;
+    }
+#endif
     struct _Task_impl_base;
-    template<typename _ReturnType, typename _Result> struct _Task_impl;
+    template<typename _ReturnType> struct _Task_impl;
 
-    template<typename _ReturnType, typename _Result = details::_Unit_type>
+    template<typename _ReturnType>
     struct _Task_ptr
     {
-        typedef std::shared_ptr<_Task_impl<_ReturnType, _Result>> _Type;
-        static _Type _Make(Concurrency::details::_CancellationTokenState * _Ct) { return std::make_shared<_Task_impl<_ReturnType, _Result>>(_Ct); }
+        typedef std::shared_ptr<_Task_impl<_ReturnType>> _Type;
+#if _MSC_VER >= 1800
+        static _Type _Make(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler_arg) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct, _Scheduler_arg); }
+#else
+        static _Type _Make(Concurrency::details::_CancellationTokenState * _Ct) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct); }
+#endif
     };
-
+#if _MSC_VER >= 1800
+    typedef Concurrency::details::_TaskCollection_t::_TaskProcHandle_t _UnrealizedChore_t;
+    typedef _UnrealizedChore_t _UnrealizedChore;
+    typedef Concurrency::extensibility::scoped_critical_section_t scoped_lock;
+    typedef Concurrency::extensibility::critical_section_t critical_section;
+    typedef Concurrency::details::atomic_size_t atomic_size_t;
+#else
+    typedef Concurrency::details::_UnrealizedChore _UnrealizedChore;
+    typedef Concurrency::critical_section::scoped_lock scoped_lock;
+    typedef Concurrency::critical_section critical_section;
+    typedef volatile size_t atomic_size_t;
+#endif
     typedef std::shared_ptr<_Task_impl_base> _Task_ptr_base;
     // The weak-typed base task handler for continuation tasks.
-    struct _ContinuationTaskHandleBase : Concurrency::details::_UnrealizedChore
+    struct _ContinuationTaskHandleBase : _UnrealizedChore
     {
         _ContinuationTaskHandleBase * _M_next;
         task_continuation_context _M_continuationContext;
         bool _M_isTaskBasedContinuation;
 
         // This field gives inlining scheduling policy for current chore.
-        Concurrency::details::_TaskInliningMode _M_inliningMode;
+        _TaskInliningMode _M_inliningMode;
 
         virtual _Task_ptr_base _GetTaskImplBase() const = 0;
 
@@ -1554,7 +2263,157 @@ namespace details
         }
         virtual ~_ContinuationTaskHandleBase() {}
     };
+#if _MSC_VER >= 1800
+#if _PPLTASK_ASYNC_LOGGING
+    // GUID used for identifying causality logs from PPLTask
+    const ::Platform::Guid _PPLTaskCausalityPlatformID(0x7A76B220, 0xA758, 0x4E6E, 0xB0, 0xE0, 0xD7, 0xC6, 0xD7, 0x4A, 0x88, 0xFE);
+
+    __declspec(selectany) volatile long _isCausalitySupported = 0;
+
+    inline bool _IsCausalitySupported()
+    {
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+        if (_isCausalitySupported == 0)
+        {
+            long _causality = 1;
+            OSVERSIONINFOEX _osvi = {};
+            _osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+            // The Causality is supported on Windows version higher than Windows 8
+            _osvi.dwMajorVersion = 6;
+            _osvi.dwMinorVersion = 3;
+
+            DWORDLONG _conditionMask = 0;
+            VER_SET_CONDITION(_conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+            VER_SET_CONDITION(_conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
+
+            if (::VerifyVersionInfo(&_osvi, VER_MAJORVERSION | VER_MINORVERSION, _conditionMask))
+            {
+                _causality = 2;
+            }
+
+            _isCausalitySupported = _causality;
+            return _causality == 2;
+        }
+
+        return _isCausalitySupported == 2 ? true : false;
+#else
+        return true;
+#endif
+    }
+
+    // Stateful logger rests inside task_impl_base.
+    struct _TaskEventLogger
+    {
+        _Task_impl_base *_M_task;
+        bool _M_scheduled;
+        bool _M_taskPostEventStarted;
+
+        // Log before scheduling task
+        void _LogScheduleTask(bool _isContinuation)
+        {
+            if (details::_IsCausalitySupported())
+            {
+                ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationCreation(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
+                    _PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task),
+                    _isContinuation ? "Concurrency::PPLTask::ScheduleContinuationTask" : "Concurrency::PPLTask::ScheduleTask", 0);
+                _M_scheduled = true;
+            }
+        }
+
+        // It will log the cancel event but not canceled state. _LogTaskCompleted will log the terminal state, which includes cancel state.
+        void _LogCancelTask()
+        {
+            if (details::_IsCausalitySupported())
+            {
+                ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationRelation(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Important, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
+                    _PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), ::Windows::Foundation::Diagnostics::CausalityRelation::Cancel);
+
+            }
+        }
+
+        // Log when task reaches terminal state. Note: the task can reach a terminal state (by cancellation or exception) without having run
+        void _LogTaskCompleted();
+
+        // Log when task body (which includes user lambda and other scheduling code) begin to run
+        void _LogTaskExecutionStarted() { }
+
+        // Log when task body finish executing
+        void _LogTaskExecutionCompleted()
+        {
+            if (_M_taskPostEventStarted && details::_IsCausalitySupported())
+            {
+                ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
+                    ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::CompletionNotification);
+            }
+        }
+
+        // Log right before user lambda being invoked
+        void _LogWorkItemStarted()
+        {
+            if (details::_IsCausalitySupported())
+            {
+                ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkStart(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
+                    _PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::Execution);
+            }
+        }
+
+        // Log right after user lambda being invoked
+        void _LogWorkItemCompleted()
+        {
+            if (details::_IsCausalitySupported())
+            {
+                ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
+                    ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::Execution);
+
+                ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkStart(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
+                    _PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::CompletionNotification);
+                _M_taskPostEventStarted = true;
+            }
+        }
+
+        _TaskEventLogger(_Task_impl_base *_task) : _M_task(_task)
+        {
+            _M_scheduled = false;
+            _M_taskPostEventStarted = false;
+        }
+    };
+
+    // Exception safe logger for user lambda
+    struct _TaskWorkItemRAIILogger
+    {
+        _TaskEventLogger &_M_logger;
+        _TaskWorkItemRAIILogger(_TaskEventLogger &_taskHandleLogger) : _M_logger(_taskHandleLogger)
+        {
+            _M_logger._LogWorkItemStarted();
+        }
+
+        ~_TaskWorkItemRAIILogger()
+        {
+            _M_logger._LogWorkItemCompleted();
+        }
+        _TaskWorkItemRAIILogger &operator =(const _TaskWorkItemRAIILogger &); // cannot be assigned
+    };
 
+#else
+    inline void _LogCancelTask(_Task_impl_base *) {}
+    struct _TaskEventLogger
+    {
+        void _LogScheduleTask(bool) {}
+        void _LogCancelTask() {}
+        void _LogWorkItemStarted() {}
+        void _LogWorkItemCompleted() {}
+        void _LogTaskExecutionStarted() {}
+        void _LogTaskExecutionCompleted() {}
+        void _LogTaskCompleted() {}
+        _TaskEventLogger(_Task_impl_base *) {}
+    };
+    struct _TaskWorkItemRAIILogger
+    {
+        _TaskWorkItemRAIILogger(_TaskEventLogger &) {}
+    };
+#endif
+#endif
     /// <summary>
     ///     The _PPLTaskHandle is the strong-typed task handle base. All user task functions need to be wrapped in this task handler
     ///     to be executable by PPL. By deriving from a different _BaseTaskHandle, it can be used for both initial tasks and continuation tasks.
@@ -1575,18 +2434,35 @@ namespace details
     {
         _PPLTaskHandle(const typename _Task_ptr<_ReturnType>::_Type & _PTask) : _M_pTask(_PTask)
         {
+#if _MSC_VER < 1800
             m_pFunction = reinterpret_cast <Concurrency::TaskProc> (&_UnrealizedChore::_InvokeBridge<_PPLTaskHandle>);
             _SetRuntimeOwnsLifetime(true);
+#endif
+        }
+        virtual ~_PPLTaskHandle() {
+#if _MSC_VER >= 1800
+            // Here is the sink of all task completion code paths
+            _M_pTask->_M_taskEventLogger._LogTaskCompleted();
+#endif
         }
-        virtual ~_PPLTaskHandle() {}
+#if _MSC_VER >= 1800
+        virtual void invoke() const
+#else
         void operator()() const
+#endif
         {
             // All exceptions should be rethrown to finish cleanup of the task collection. They will be caught and handled
             // by the runtime.
             _CONCRT_ASSERT(_M_pTask != nullptr);
-            if (!_M_pTask->_TransitionedToStarted())
+            if (!_M_pTask->_TransitionedToStarted()) {
+#if _MSC_VER >= 1800
+                static_cast<const _DerivedTaskHandle *>(this)->_SyncCancelAndPropagateException();
+#endif
                 return;
-
+            }
+#if _MSC_VER >= 1800
+            _M_pTask->_M_taskEventLogger._LogTaskExecutionStarted();
+#endif
             try
             {
                 // All derived task handle must implement this contract function.
@@ -1595,23 +2471,34 @@ namespace details
             catch (const Concurrency::task_canceled &)
             {
                 _M_pTask->_Cancel(true);
+#if _MSC_VER < 1800
                 throw;
+#endif
             }
             catch (const Concurrency::details::_Interruption_exception &)
             {
                 _M_pTask->_Cancel(true);
+#if _MSC_VER < 1800
                 throw;
+#endif
             }
-            catch(IRestrictedErrorInfo*& _E)
+            catch (IRestrictedErrorInfo*& _E)
             {
                 _M_pTask->_CancelWithException(_E);
+#if _MSC_VER < 1800
                 throw;
+#endif
             }
             catch (...)
             {
                 _M_pTask->_CancelWithException(std::current_exception());
+#if _MSC_VER < 1800
                 throw;
+#endif
             }
+#if _MSC_VER >= 1800
+            _M_pTask->_M_taskEventLogger._LogTaskExecutionCompleted();
+#endif
         }
 
         // Cast _M_pTask pointer to "type-less" _Task_impl_base pointer, which can be used in _ContinuationTaskHandleBase.
@@ -1643,10 +2530,18 @@ namespace details
             _Completed,
             _Canceled
         };
+#if _MSC_VER >= 1800
+        _Task_impl_base(Concurrency::details::_CancellationTokenState * _PTokenState, Concurrency::scheduler_ptr _Scheduler_arg)
+            : _M_TaskState(_Created),
+            _M_fFromAsync(false), _M_fUnwrappedTask(false),
+            _M_pRegistration(nullptr), _M_Continuations(nullptr), _M_TaskCollection(_Scheduler_arg),
+            _M_taskEventLogger(this)
+#else
         _Task_impl_base(Concurrency::details::_CancellationTokenState * _PTokenState) : _M_TaskState(_Created),
             _M_fFromAsync(false), _M_fRuntimeAggregate(false), _M_fUnwrappedTask(false),
             _M_pRegistration(nullptr), _M_Continuations(nullptr), _M_pTaskCollection(nullptr),
             _M_pTaskCreationAddressHint(nullptr)
+#endif
         {
             // Set cancelation token
             _M_pTokenState = _PTokenState;
@@ -1663,12 +2558,13 @@ namespace details
             {
                 _M_pTokenState->_Release();
             }
-
+#if _MSC_VER < 1800
             if (_M_pTaskCollection != nullptr)
             {
                 _M_pTaskCollection->_Release();
                 _M_pTaskCollection = nullptr;
             }
+#endif
         }
 
         task_status _Wait()
@@ -1696,6 +2592,7 @@ namespace details
             }
             if (_DoWait)
             {
+#if _MSC_VER < 1800
                 // Wait for the task to be actually scheduled, otherwise the underlying task collection
                 // might not be created yet. If we don't wait, we will miss the chance to inline this task.
                 _M_Scheduled.wait();
@@ -1704,12 +2601,21 @@ namespace details
                 // A PPL task created by a task_completion_event does not have an underlying TaskCollection. For
                 // These tasks, a call to wait should wait for the event to be set. The TaskCollection must either
                 // be nullptr or allocated (the setting of _M_Scheduled) ensures that.
+#endif
                 // If this task was created from a Windows Runtime async operation, do not attempt to inline it. The
                 // async operation will take place on a thread in the appropriate apartment Simply wait for the completed
                 // event to be set.
+#if _MSC_VER >= 1800
+                if (_M_fFromAsync)
+#else
                 if ((_M_pTaskCollection == nullptr) || _M_fFromAsync)
+#endif
                 {
+#if _MSC_VER >= 1800
+                    _M_TaskCollection._Wait();
+#else
                     _M_Completed.wait();
+#endif
                 }
                 else
                 {
@@ -1726,7 +2632,11 @@ namespace details
                         // When it returns cancelled, either work chore or the cancel thread should already have set task's state
                         // properly -- cancelled state or completed state (because there was no interruption point).
                         // For tasks with unwrapped tasks, we should not change the state of current task, since the unwrapped task are still running.
+#if _MSC_VER >= 1800
+                        _M_TaskCollection._RunAndWait();
+#else
                         _M_pTaskCollection->_RunAndWait();
+#endif
                     }
                     catch (Concurrency::details::_Interruption_exception&)
                     {
@@ -1741,7 +2651,7 @@ namespace details
                         // the exception and canceled the task. Swallow the exception here.
                         _CONCRT_ASSERT(_IsCanceled());
                     }
-                    catch(IRestrictedErrorInfo*& _E)
+                    catch (IRestrictedErrorInfo*& _E)
                     {
                         // Its possible the task body hasn't seen the exception, if so we need to cancel with exception here.
                         if(!_HasUserException())
@@ -1768,7 +2678,11 @@ namespace details
                     // however, this takes the tact of simply waiting upon the completion signal.
                     if (_M_fUnwrappedTask)
                     {
+#if _MSC_VER >= 1800
+                        _M_TaskCollection._Wait();
+#else
                         _M_Completed.wait();
+#endif
                     }
                 }
             }
@@ -1821,19 +2735,44 @@ namespace details
         {
             // This task was canceled because the task body encountered an exception.
             _CONCRT_ASSERT(!_HasUserException());
+#if _MSC_VER >= 1800
+            return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack()));
+#else
             return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationAddressHint()));
+#endif
         }
         bool _CancelWithException(const std::exception_ptr& _Exception)
         {
             // This task was canceled because the task body encountered an exception.
             _CONCRT_ASSERT(!_HasUserException());
+#if _MSC_VER >= 1800
+            return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack()));
+#else
             return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationAddressHint()));
+#endif
         }
 
+#if _MSC_VER >= 1800
+        void _RegisterCancellation(std::weak_ptr<_Task_impl_base> _WeakPtr)
+#else
         void _RegisterCancellation()
+#endif
         {
             _CONCRT_ASSERT(Concurrency::details::_CancellationTokenState::_IsValid(_M_pTokenState));
+#if _MSC_VER >= 1800
+            auto _CancellationCallback = [_WeakPtr](){
+                // Taking ownership of the task prevents dead lock during destruction
+                // if the destructor waits for the cancellations to be finished
+                auto _task = _WeakPtr.lock();
+                if (_task != nullptr)
+                    _task->_Cancel(false);
+            };
+
+            _M_pRegistration = new Concurrency::details::_CancellationTokenCallback<decltype(_CancellationCallback)>(_CancellationCallback);
+            _M_pTokenState->_RegisterCallback(_M_pRegistration);
+#else
             _M_pRegistration = _M_pTokenState->_RegisterCallback(reinterpret_cast<Concurrency::TaskProc>(&_CancelViaToken), (_Task_impl_base *)this);
+#endif
         }
 
         void _DeregisterCancellation()
@@ -1845,12 +2784,12 @@ namespace details
                 _M_pRegistration = nullptr;
             }
         }
-
+#if _MSC_VER < 1800
         static void _CancelViaToken(_Task_impl_base *_PImpl)
         {
             _PImpl->_Cancel(false);
         }
-
+#endif
         bool _IsCreated()
         {
             return (_M_TaskState == _Created);
@@ -1878,14 +2817,14 @@ namespace details
 
         bool _HasUserException()
         {
-            return _M_exceptionHolder != nullptr;
+            return static_cast<bool>(_M_exceptionHolder);
         }
-
+#if _MSC_VER < 1800
         void _SetScheduledEvent()
         {
             _M_Scheduled.set();
         }
-
+#endif
         const std::shared_ptr<_ExceptionHolder>& _GetExceptionHolder()
         {
             _CONCRT_ASSERT(_HasUserException());
@@ -1901,7 +2840,17 @@ namespace details
         {
             _M_fFromAsync = _Async;
         }
+#if _MSC_VER >= 1800
+        _TaskCreationCallstack _GetTaskCreationCallstack()
+        {
+            return _M_pTaskCreationCallstack;
+        }
 
+        void _SetTaskCreationCallstack(const _TaskCreationCallstack &_Callstack)
+        {
+            _M_pTaskCreationCallstack = _Callstack;
+        }
+#else
         void* _GetTaskCreationAddressHint()
         {
             return _M_pTaskCreationAddressHint;
@@ -1911,7 +2860,7 @@ namespace details
         {
             _M_pTaskCreationAddressHint = _AddressHint;
         }
-
+#endif
         /// <summary>
         ///     Helper function to schedule the task on the Task Collection.
         /// </summary>
@@ -1921,16 +2870,21 @@ namespace details
         /// <param name="_InliningMode">
         ///     The inlining scheduling policy for current _PTaskHandle.
         /// </param>
-        void _ScheduleTask(Concurrency::details::_UnrealizedChore * _PTaskHandle, Concurrency::details::_TaskInliningMode _InliningMode)
+        void _ScheduleTask(_UnrealizedChore * _PTaskHandle, _TaskInliningMode _InliningMode)
         {
+#if _MSC_VER < 1800
             // Construct the task collection; We use none token to provent it becoming interruption point.
             _M_pTaskCollection = Concurrency::details::_AsyncTaskCollection::_NewCollection(Concurrency::details::_CancellationTokenState::_None());
-
             // _M_pTaskCollection->_ScheduleWithAutoInline will schedule the chore onto AsyncTaskCollection with automatic inlining, in a way that honors cancellation etc.
+#endif
             try
             {
+#if _MSC_VER >= 1800
+                _M_TaskCollection._ScheduleTask(_PTaskHandle, _InliningMode);
+#else
                 // Do not need to check its returning state, more details please refer to _Wait method.
                 _M_pTaskCollection->_ScheduleWithAutoInline(_PTaskHandle, _InliningMode);
+#endif
             }
             catch (const Concurrency::task_canceled &)
             {
@@ -1951,12 +2905,13 @@ namespace details
                 // and the task should be canceled with exception. Swallow the exception here.
                 _CONCRT_ASSERT(_HasUserException());
             }
-
+#if _MSC_VER < 1800
             // Set the event in case anyone is waiting to notify that this task has been scheduled. In the case where we
             // execute the chore inline, the event should be set after the chore has executed, to prevent a different thread
             // performing a wait on the task from waiting on the task collection before the chore is actually added to it,
             // and thereby returning from the wait() before the chore has executed.
             _SetScheduledEvent();
+#endif
         }
 
         /// <summary>
@@ -1991,11 +2946,16 @@ namespace details
                 // (with or without a user exception).
                 _CONCRT_ASSERT(_IsCompleted() || _PTaskHandle->_M_isTaskBasedContinuation);
 
+#if _MSC_VER >= 1800
+                _CONCRT_ASSERT(!_ImplBase->_IsCanceled());
+                return _ImplBase->_ScheduleContinuationTask(_PTaskHandle);
+#else
                 // If it has been canceled here (before starting), do nothing. The guy firing cancel will do the clean up.
                 if (!_ImplBase->_IsCanceled())
                 {
                     return _ImplBase->_ScheduleContinuationTask(_PTaskHandle);
                 }
+#endif
             }
 
             // If the handle is not scheduled, we need to manually delete it.
@@ -2005,6 +2965,9 @@ namespace details
         // Schedule a continuation to run
         void _ScheduleContinuationTask(_ContinuationTaskHandleBase * _PTaskHandle)
         {
+#if _MSC_VER >= 1800
+            _M_taskEventLogger._LogScheduleTask(true);
+#endif
             // Ensure that the continuation runs in proper context (this might be on a Concurrency Runtime thread or in a different Windows Runtime apartment)
             if (_PTaskHandle->_M_continuationContext._HasCapturedContext())
             {
@@ -2016,7 +2979,7 @@ namespace details
                 {
                     _PTaskHandle->_M_inliningMode = Concurrency::details::_DefaultAutoInline;
                 }
-                details::_ScheduleFuncWithAutoInline([_PTaskHandle]() {
+                details::_ScheduleFuncWithAutoInline([_PTaskHandle]() -> HRESULT {
                     // Note that we cannot directly capture "this" pointer, instead, we should use _TaskImplPtr, a shared_ptr to the _Task_impl_base.
                     // Because "this" pointer will be invalid as soon as _PTaskHandle get deleted. _PTaskHandle will be deleted after being scheduled.
                     auto _TaskImplPtr = _PTaskHandle->_GetTaskImplBase();
@@ -2036,12 +2999,14 @@ namespace details
                         //
                         try
                         {
-                            _PTaskHandle->_M_continuationContext._CallInContext([_PTaskHandle, _TaskImplPtr]() -> HRESULT {
-                                _TaskImplPtr->_ScheduleTask(_PTaskHandle, Concurrency::details::_ForceInline);
+                            // Dev10 compiler needs this!
+                            auto _PTaskHandle1 = _PTaskHandle;
+                            _PTaskHandle->_M_continuationContext._CallInContext([_PTaskHandle1, _TaskImplPtr]() -> HRESULT {
+                                _TaskImplPtr->_ScheduleTask(_PTaskHandle1, Concurrency::details::_ForceInline);
                                 return S_OK;
                             });
                         }
-                        catch(IRestrictedErrorInfo*& _E)
+                        catch (IRestrictedErrorInfo*& _E)
                         {
                             _TaskImplPtr->_CancelWithException(_E);
                         }
@@ -2050,6 +3015,7 @@ namespace details
                             _TaskImplPtr->_CancelWithException(std::current_exception());
                         }
                     }
+                    return S_OK;
                 }, _PTaskHandle->_M_inliningMode);
             }
             else
@@ -2076,7 +3042,7 @@ namespace details
             // If the task has canceled, cancel the continuation. If the task has completed, execute the continuation right away.
             // Otherwise, add it to the list of pending continuations
             {
-                Concurrency::critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);
+                scoped_lock _LockHolder(_M_ContinuationsCritSec);
                 if (_IsCompleted() || (_IsCanceled() && _PTaskHandle->_M_isTaskBasedContinuation))
                 {
                     _Do = _Schedule;
@@ -2194,37 +3160,46 @@ namespace details
             return false;
         }
 
-        template<typename _ReturnType, typename _Result>
-        static void _AsyncInit(const typename _Task_ptr<_ReturnType, _Result>::_Type & _OuterTask,
-            ABI::Windows::Foundation::IAsyncOperation<_Result>* _AsyncOp)
+        template<typename _ReturnType, typename _Result, typename _OpType, typename _CompHandlerType, typename _ResultType>
+        static void _AsyncInit(const typename _Task_ptr<_ReturnType>::_Type & _OuterTask,
+            _AsyncInfoImpl<_OpType, _CompHandlerType, _ResultType>* _AsyncOp)
         {
+            typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_GetUnwrappedType(stdx::declval<_OpType*>()))>::type _Result_abi;
             // This method is invoked either when a task is created from an existing async operation or
             // when a lambda that creates an async operation executes.
 
             // If the outer task is pending cancel, cancel the async operation before setting the completed handler. The COM reference on
             // the IAsyncInfo object will be released when all *references to the operation go out of scope.
+
+            // This assertion uses the existence of taskcollection to determine if the task was created from an event.
+            // That is no longer valid as even tasks created from a user lambda could have no underlying taskcollection
+            // when a custom scheduler is used.
+#if _MSC_VER < 1800
             _CONCRT_ASSERT(((_OuterTask->_M_pTaskCollection == nullptr) || _OuterTask->_M_fUnwrappedTask) && !_OuterTask->_IsCanceled());
+#endif
 
             // Pass the shared_ptr by value into the lambda instead of using 'this'.
-            _AsyncOp->put_Completed(create_completionhandler<ABI::Windows::Foundation::IAsyncOperation<_Result>, ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>>(
-                [_OuterTask](ABI::Windows::Foundation::IAsyncOperation<_Result>* _Operation, ABI::Windows::Foundation::AsyncStatus _Status) mutable -> HRESULT
+
+            _AsyncOp->put_Completed(Microsoft::WRL::Callback<_CompHandlerType>(
+                [_OuterTask, _AsyncOp](_OpType* _Operation, ABI::Windows::Foundation::AsyncStatus _Status) mutable -> HRESULT
             {
+                HRESULT hr = S_OK;
                 if (_Status == ABI::Windows::Foundation::AsyncStatus::Canceled)
                 {
                     _OuterTask->_Cancel(true);
                 }
                 else if (_Status == ABI::Windows::Foundation::AsyncStatus::Error)
                 {
-                    HRESULT hr;
+                    HRESULT _hr;
                     Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
-                    if (SUCCEEDED(_Operation->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())) && SUCCEEDED(pAsyncInfo->get_ErrorCode(&hr)))
-                        _OuterTask->_CancelWithException(std::make_exception_ptr(hr));
+                    if (SUCCEEDED(hr = _Operation->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())) && SUCCEEDED(hr = pAsyncInfo->get_ErrorCode(&_hr)))
+                        _OuterTask->_CancelWithException(std::make_exception_ptr(_hr));
                 }
                 else
                 {
                     _CONCRT_ASSERT(_Status == ABI::Windows::Foundation::AsyncStatus::Completed);
-                    _Result results;
-                    if (SUCCEEDED(_Operation->GetResults(&results)))
+                    _NormalizeVoidToUnitType<_Result_abi>::_Type results;
+                    if (SUCCEEDED(hr = _AsyncOp->GetResults(&results)))
                         _OuterTask->_FinalizeAndRunContinuations(results);
                 }
                 // Take away this shared pointers reference on the task instead of waiting for the delegate to be released. It could
@@ -2232,9 +3207,9 @@ namespace details
                 // on to resources longer than they should. As an example, without this reset, writing to a file followed by reading from
                 // it using the Windows Runtime Async APIs causes a sharing violation.
                 // Using const_cast is the workaround for failed mutable keywords
-                const_cast<_Task_ptr<_ReturnType, _Result>::_Type &>(_OuterTask).reset();
-                return S_OK;
-            }));
+                const_cast<_Task_ptr<_ReturnType>::_Type &>(_OuterTask).reset();
+                return hr;
+            }).Get());
             _OuterTask->_SetUnwrappedAsyncOp(_AsyncOp);
         }
         template<typename _ReturnType, typename _InternalReturnType>
@@ -2248,7 +3223,7 @@ namespace details
             // the exception from being marked as observed by our internal continuation. This continuation must be scheduled regardless
             // of whether or not the _OuterTask task is canceled.
             //
-            _UnwrappedTask._Then([_OuterTask](task<_InternalReturnType> _AncestorTask) {
+            _UnwrappedTask._Then([_OuterTask](task<_InternalReturnType> _AncestorTask) -> HRESULT {
 
                 if (_AncestorTask._GetImpl()->_IsCompleted())
                 {
@@ -2268,20 +3243,34 @@ namespace details
                         _OuterTask->_Cancel(true);
                     }
                 }
-            }, nullptr, false, details::_DefaultAutoInline);
+                return S_OK;
+#if _MSC_VER >= 1800
+            }, nullptr, Concurrency::details::_DefaultAutoInline);
+#else
+            }, nullptr, false, Concurrency::details::_DefaultAutoInline);
+#endif
         }
 
+#if _MSC_VER >= 1800
+        Concurrency::scheduler_ptr _GetScheduler() const
+        {
+            return _M_TaskCollection._GetScheduler();
+        }
+#else
         Concurrency::event _M_Completed;
         Concurrency::event _M_Scheduled;
+#endif
 
         // Tracks the internal state of the task
-        _TaskInternalState _M_TaskState;
+        volatile _TaskInternalState _M_TaskState;
         // Set to true either if the ancestor task had the flag set to true, or if the lambda that does the work of this task returns an
         // async operation or async action that is unwrapped by the runtime.
         bool _M_fFromAsync;
+#if _MSC_VER < 1800
         // Set to true if we need to marshal the inner parts of an aggregate type like std::vector<T^> or std::pair<T^, size_t>. We only marshal
         // the contained T^s if we create the vector or pair, such as on a when_any or a when_all operation.
         bool _M_fRuntimeAggregate;
+#endif
         // Set to true when a continuation unwraps a task or async operation.
         bool _M_fUnwrappedTask;
 
@@ -2292,7 +3281,7 @@ namespace details
 
         typedef _ContinuationTaskHandleBase * _ContinuationList;
 
-        Concurrency::critical_section _M_ContinuationsCritSec;
+        critical_section _M_ContinuationsCritSec;
         _ContinuationList _M_Continuations;
 
         // The cancellation token state.
@@ -2302,21 +3291,60 @@ namespace details
         Concurrency::details::_CancellationTokenRegistration * _M_pRegistration;
 
         // The async task collection wrapper
+#if _MSC_VER >= 1800
+        Concurrency::details::_TaskCollection_t _M_TaskCollection;
+
+        // Callstack for function call (constructor or .then) that created this task impl.
+        _TaskCreationCallstack _M_pTaskCreationCallstack;
+
+        _TaskEventLogger _M_taskEventLogger;
+#else
         Concurrency::details::_AsyncTaskCollection * _M_pTaskCollection;
 
         // Points to the source code instruction right after the function call (constructor or .then) that created this task impl.
         void* _M_pTaskCreationAddressHint;
+#endif
 
     private:
         // Must not be copied by value:
         _Task_impl_base(const _Task_impl_base&);
         _Task_impl_base const & operator=(_Task_impl_base const&);
     };
-    template<typename _ReturnType, typename _Result = details::_Unit_type>
+
+#if _MSC_VER >= 1800
+#if _PPLTASK_ASYNC_LOGGING
+    inline void _TaskEventLogger::_LogTaskCompleted()
+    {
+        if (_M_scheduled)
+        {
+            ::Windows::Foundation::AsyncStatus _State;
+            if (_M_task->_IsCompleted())
+                _State = ::Windows::Foundation::AsyncStatus::Completed;
+            else if (_M_task->_HasUserException())
+                _State = ::Windows::Foundation::AsyncStatus::Error;
+            else
+                _State = ::Windows::Foundation::AsyncStatus::Canceled;
+
+            if (details::_IsCausalitySupported())
+            {
+                ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
+                    _PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), _State);
+            }
+        }
+    }
+#endif
+#endif
+
+    template<typename _ReturnType>
     struct _Task_impl : public _Task_impl_base
     {
-        typedef ABI::Windows::Foundation::IAsyncOperation<_Result> _AsyncOperationType;
+        typedef ABI::Windows::Foundation::IAsyncInfo _AsyncOperationType;
+#if _MSC_VER >= 1800
+        _Task_impl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler_arg)
+            : _Task_impl_base(_Ct, _Scheduler_arg)
+#else
         _Task_impl(Concurrency::details::_CancellationTokenState * _Ct) : _Task_impl_base(_Ct)
+#endif
         {
             _M_unwrapped_async_op = nullptr;
         }
@@ -2328,17 +3356,18 @@ namespace details
         }
         virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr<_ExceptionHolder> & _ExceptionHolder)
         {
-            bool _RunContinuations = false;
+            enum { _Nothing, _RunContinuations, _Cancel } _Do = _Nothing;
             {
-                Concurrency::critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);
+                scoped_lock _LockHolder(_M_ContinuationsCritSec);
                 if (_UserException)
                 {
                     _CONCRT_ASSERT(_SynchronousCancel && !_IsCompleted());
                     // If the state is _Canceled, the exception has to be coming from an ancestor.
                     _CONCRT_ASSERT(!_IsCanceled() || _PropagatedFromAncestor);
+#if _MSC_VER < 1800
                     // If the state is _Started or _PendingCancel, the exception cannot be coming from an ancestor.
                     _CONCRT_ASSERT((!_IsStarted() && !_IsPendingCancel()) || !_PropagatedFromAncestor);
-
+#endif
                     // We should not be canceled with an exception more than once.
                     _CONCRT_ASSERT(!_HasUserException());
 
@@ -2365,20 +3394,50 @@ namespace details
                     _CONCRT_ASSERT(!_SynchronousCancel || !_HasUserException());
                 }
 
+#if _MSC_VER >= 1800
+                if (_SynchronousCancel)
+#else
                 if (_SynchronousCancel || _IsCreated())
+#endif
                 {
                     // Be aware that this set must be done BEFORE _M_Scheduled being set, or race will happen between this and wait()
                     _M_TaskState = _Canceled;
+#if _MSC_VER < 1800
                     _M_Scheduled.set();
+#endif
 
                     // Cancellation completes the task, so all dependent tasks must be run to cancel them
                     // They are canceled when they begin running (see _RunContinuation) and see that their
                     // ancestor has been canceled.
-                    _RunContinuations = true;
+                    _Do = _RunContinuations;
                 }
                 else
                 {
+#if _MSC_VER >= 1800
+                    _CONCRT_ASSERT(!_UserException);
+
+                    if (_IsStarted())
+                    {
+                        // should not initiate cancellation under a lock
+                        _Do = _Cancel;
+                    }
+
+                    // The _M_TaskState variable transitions to _Canceled when cancellation is completed (the task is not executing user code anymore).
+                    // In the case of a synchronous cancel, this can happen immediately, whereas with an asynchronous cancel, the task has to move from
+                    // _Started to _PendingCancel before it can move to _Canceled when it is finished executing.
+                    _M_TaskState = _PendingCancel;
+
+                    _M_taskEventLogger._LogCancelTask();
+                }
+            }
+
+            switch (_Do)
+            {
+            case _Cancel:
+            {
+#else
                     _CONCRT_ASSERT(_IsStarted() && !_UserException);
+#endif
                     // The _M_TaskState variable transitions to _Canceled when cancellation is completed (the task is not executing user code anymore).
                     // In the case of a synchronous cancel, this can happen immediately, whereas with an asynchronous cancel, the task has to move from
                     // _Started to _PendingCancel before it can move to _Canceled when it is finished executing.
@@ -2386,43 +3445,61 @@ namespace details
                     if (_M_unwrapped_async_op != nullptr)
                     {
                         // We will only try to cancel async operation but not unwrapped tasks, since unwrapped tasks cannot be canceled without its token.
-                        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
-                        if (SUCCEEDED(_M_unwrapped_async_op.As(&pAsyncInfo)))
-                            pAsyncInfo->Cancel();
+                        if (_M_unwrapped_async_op)    _M_unwrapped_async_op->Cancel();
                     }
-                }
-
+#if _MSC_VER >= 1800
+                        _M_TaskCollection._Cancel();
+                        break;
+#else
                 // Optimistic trying for cancelation
                 if (_M_pTaskCollection != nullptr)
                 {
                     _M_pTaskCollection->_Cancel();
                 }
+#endif
+                }
+#if _MSC_VER < 1800
             }
+#endif
 
             // Only execute continuations and mark the task as completed if we were able to move the task to the _Canceled state.
+#if _MSC_VER >= 1800
+            case _RunContinuations:
+            {
+                _M_TaskCollection._Complete();
+#else
             if (_RunContinuations)
             {
                 _M_Completed.set();
+#endif
 
                 if (_M_Continuations)
                 {
                     // Scheduling cancellation with automatic inlining.
-                    details::_ScheduleFuncWithAutoInline([=](){ _RunTaskContinuations(); }, Concurrency::details::_DefaultAutoInline);
+                    details::_ScheduleFuncWithAutoInline([=]() -> HRESULT { _RunTaskContinuations(); return S_OK; }, Concurrency::details::_DefaultAutoInline);
                 }
+#if _MSC_VER >= 1800
+                break;
+            }
+#endif
             }
             return true;
         }
         void _FinalizeAndRunContinuations(_ReturnType _Result)
         {
-            _M_Result = _Result;
 
+#if _MSC_VER >= 1800
+            _M_Result.Set(_Result);
+#else
+            _M_Result = _Result;
             _M_ResultContext = _ResultContext<_ReturnType>::_GetContext(_M_fRuntimeAggregate);
+#endif
             {
                 //
                 // Hold this lock to ensure continuations being concurrently either get added
                 // to the _M_Continuations vector or wait for the result
                 //
-                Concurrency::critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);
+                scoped_lock _LockHolder(_M_ContinuationsCritSec);
 
                 // A task could still be in the _Created state if it was created with a task_completion_event.
                 // It could also be in the _Canceled state for the same reason.
@@ -2435,7 +3512,11 @@ namespace details
                 // Always transition to "completed" state, even in the face of unacknowledged pending cancellation
                 _M_TaskState = _Completed;
             }
+#if _MSC_VER >= 1800
+            _M_TaskCollection._Complete();
+#else
             _M_Completed.set();
+#endif
             _RunTaskContinuations();
         }
         //
@@ -2443,8 +3524,14 @@ namespace details
         //
         bool _TransitionedToStarted()
         {
-            Concurrency::critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);
+            scoped_lock _LockHolder(_M_ContinuationsCritSec);
+#if _MSC_VER >= 1800
+            // Canceled state could only result from antecedent task's canceled state, but that code path will not reach here.
+            _ASSERT(!_IsCanceled());
+            if (_IsPendingCancel())
+#else
             if (_IsCanceled())
+#endif
             {
                 return false;
             }
@@ -2454,32 +3541,54 @@ namespace details
         }
         void _SetUnwrappedAsyncOp(_AsyncOperationType* _AsyncOp)
         {
-            Concurrency::critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);
+            scoped_lock _LockHolder(_M_ContinuationsCritSec);
             // Cancel the async operation if the task itself is canceled, since the thread that canceled the task missed it.
             if (_IsPendingCancel())
             {
                 _CONCRT_ASSERT(!_IsCanceled());
-                Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
-                if (SUCCEEDED(_AsyncOp->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(&pAsyncInfo)))
-                    pAsyncInfo->Cancel();
+                if (_AsyncOp) _AsyncOp->Cancel();
             }
             else
             {
                 _M_unwrapped_async_op = _AsyncOp;
             }
         }
+#if _MSC_VER >= 1800
+        // Return true if the task has reached a terminal state
+        bool _IsDone()
+        {
+            return _IsCompleted() || _IsCanceled();
+        }
+#endif
         _ReturnType _GetResult()
         {
+#if _MSC_VER >= 1800
+            return _M_Result.Get();
+#else
             return _ResultContext<_ReturnType>::_GetValue(_M_Result, _M_ResultContext, _M_fRuntimeAggregate);
+#endif
         }
+#if _MSC_VER >= 1800
+        _ResultHolder<_ReturnType>                 _M_Result;        // this means that the result type must have a public default ctor.
+#else
         _ReturnType                                 _M_Result;        // this means that the result type must have a public default ctor.
+#endif
         Microsoft::WRL::ComPtr<_AsyncOperationType> _M_unwrapped_async_op;
+#if _MSC_VER < 1800
         _ContextCallback                            _M_ResultContext;
+#endif
     };
 
     template<typename _ResultType>
     struct _Task_completion_event_impl
     {
+#if _MSC_VER >= 1800
+    private:
+        _Task_completion_event_impl(const _Task_completion_event_impl&);
+        _Task_completion_event_impl& operator=(const _Task_completion_event_impl&);
+
+    public:
+#endif
         typedef std::vector<typename _Task_ptr<_ResultType>::_Type> _TaskList;
 
         _Task_completion_event_impl() : _M_fHasValue(false), _M_fIsCanceled(false)
@@ -2503,34 +3612,38 @@ namespace details
 
         // We need to protect the loop over the array, so concurrent_vector would not have helped
         _TaskList                           _M_tasks;
-        Concurrency::critical_section                    _M_taskListCritSec;
+        critical_section                    _M_taskListCritSec;
+#if _MSC_VER >= 1800
+        _ResultHolder<_ResultType>         _M_value;
+#else
         _ResultType                         _M_value;
+#endif
         std::shared_ptr<_ExceptionHolder>   _M_exceptionHolder;
         bool                                _M_fHasValue;
         bool                                _M_fIsCanceled;
     };
 
     // Utility method for dealing with void functions
-    inline std::function<_Unit_type(void)> _MakeVoidToUnitFunc(const std::function<void(void)>& _Func)
+    inline std::function<HRESULT(_Unit_type*)> _MakeVoidToUnitFunc(const std::function<HRESULT(void)>& _Func)
     {
-        return [=]() -> _Unit_type { _Func(); return _Unit_type(); };
+        return [=](_Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(); *retVal = _Unit_type(); return hr; };
     }
 
     template <typename _Type>
-    std::function<_Type(_Unit_type)> _MakeUnitToTFunc(const std::function<_Type(void)>& _Func)
+    std::function<HRESULT(_Unit_type, _Type*)> _MakeUnitToTFunc(const std::function<HRESULT(_Type*)>& _Func)
     {
-        return [=](_Unit_type) -> _Type { return _Func(); };
+        return [=](_Unit_type, _Type* retVal) -> HRESULT { HRESULT hr = _Func(retVal); return hr;  };
     }
 
     template <typename _Type>
-    std::function<_Unit_type(_Type)> _MakeTToUnitFunc(const std::function<void(_Type)>& _Func)
+    std::function<HRESULT(_Type, _Unit_type*)> _MakeTToUnitFunc(const std::function<HRESULT(_Type)>& _Func)
     {
-        return [=](_Type t) -> _Unit_type { _Func(t); return _Unit_type(); };
+        return[=](_Type t, _Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(t); *retVal = _Unit_type(); return hr;  };
     }
 
-    inline std::function<_Unit_type(_Unit_type)> _MakeUnitToUnitFunc(const std::function<void(void)>& _Func)
+    inline std::function<HRESULT(_Unit_type, _Unit_type*)> _MakeUnitToUnitFunc(const std::function<HRESULT(void)>& _Func)
     {
-        return [=](_Unit_type) -> _Unit_type { _Func(); return _Unit_type(); };
+        return [=](_Unit_type, _Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(); *retVal = _Unit_type(); return hr;  };
     }
 }
 
@@ -2591,11 +3704,15 @@ public:
         _TaskList _Tasks;
         bool _RunContinuations = false;
         {
-            Concurrency::critical_section::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
+            details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
 
             if (!_IsTriggered())
             {
+#if _MSC_VER >= 1800
+                _M_Impl->_M_value.Set(_Result);
+#else
                 _M_Impl->_M_value = _Result;
+#endif
                 _M_Impl->_M_fHasValue = true;
 
                 _Tasks.swap(_M_Impl->_M_tasks);
@@ -2607,10 +3724,23 @@ public:
         {
             for (auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt)
             {
+#if _MSC_VER >= 1800
+                // If current task was cancelled by a cancellation_token, it would be in cancel pending state.
+                if ((*_TaskIt)->_IsPendingCancel())
+                    (*_TaskIt)->_Cancel(true);
+                else
+                {
+                    // Tasks created with task_completion_events can be marked as async, (we do this in when_any and when_all
+                    // if one of the tasks involved is an async task). Since continuations of async tasks can execute inline, we
+                    // need to run continuations after the lock is released.
+                    (*_TaskIt)->_FinalizeAndRunContinuations(_M_Impl->_M_value.Get());
+                }
+#else
                 // Tasks created with task_completion_events can be marked as async, (we do this in when_any and when_all
                 // if one of the tasks involved is an async task). Since continuations of async tasks can execute inline, we
                 // need to run continuations after the lock is released.
                 (*_TaskIt)->_FinalizeAndRunContinuations(_M_Impl->_M_value);
+#endif
             }
             if (_M_Impl->_HasUserException())
             {
@@ -2621,6 +3751,16 @@ public:
 
         return false;
     }
+#if _MSC_VER >= 1800
+
+    template<typename _E>
+    __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
+        bool set_exception(_E _Except) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas
+    {
+            // It is important that _CAPTURE_CALLSTACK() evaluate to the instruction after the call instruction for set_exception.
+            return _Cancel(std::make_exception_ptr(_Except), _CAPTURE_CALLSTACK());
+    }
+#endif
 
     /// <summary>
     ///     Propagates an exception to all tasks associated with this event.
@@ -2633,8 +3773,12 @@ public:
         bool set_exception(std::exception_ptr _ExceptionPtr) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas
     {
             // It is important that _ReturnAddress() evaluate to the instruction after the call instruction for set_exception.
+#if _MSC_VER >= 1800
+            return _Cancel(_ExceptionPtr, _CAPTURE_CALLSTACK());
+#else
             return _Cancel(_ExceptionPtr, _ReturnAddress());
-        }
+#endif
+    }
 
     /// <summary>
     ///     Internal method to cancel the task_completion_event. Any task created using this event will be marked as canceled if it has
@@ -2651,11 +3795,19 @@ public:
     ///     with the same exception.
     /// </summary>
     template<typename _ExHolderType>
+#if _MSC_VER >= 1800
+    bool _Cancel(_ExHolderType _ExHolder, const details::_TaskCreationCallstack &_SetExceptionAddressHint = details::_TaskCreationCallstack()) const
+#else
     bool _Cancel(_ExHolderType _ExHolder, void* _SetExceptionAddressHint = nullptr) const
+#endif
     {
         (void)_SetExceptionAddressHint;
         bool _Canceled;
+#if _MSC_VER >= 1800
+        if(_StoreException(_ExHolder, _SetExceptionAddressHint))
+#else
         if (_StoreException(_ExHolder))
+#endif
         {
             _Canceled = _CancelInternal();
             _CONCRT_ASSERT(_Canceled);
@@ -2673,9 +3825,13 @@ public:
     ///     can bet set() successfully. If it is canceled, it will cancel with the stored exception, if one is present.
     /// </summary>
     template<typename _ExHolderType>
+#if _MSC_VER >= 1800
+    bool _StoreException(_ExHolderType _ExHolder, const details::_TaskCreationCallstack &_SetExceptionAddressHint = details::_TaskCreationCallstack()) const
+#else
     bool _StoreException(_ExHolderType _ExHolder, void* _SetExceptionAddressHint = nullptr) const
+#endif
     {
-        Concurrency::critical_section::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
+        details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
         if (!_IsTriggered() && !_M_Impl->_HasUserException())
         {
             // Create the exception holder only if we have ensured there we will be successful in setting it onto the
@@ -2696,12 +3852,20 @@ public:
 
 private:
 
+#if _MSC_VER >= 1800
+    static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder, const details::_TaskCreationCallstack&)
+#else
     static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder, void*)
+#endif
     {
         return _ExHolder;
     }
 
+#if _MSC_VER >= 1800
+    static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(std::exception_ptr _ExceptionPtr, const details::_TaskCreationCallstack &_SetExceptionAddressHint)
+#else
     static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(std::exception_ptr _ExceptionPtr, void* _SetExceptionAddressHint)
+#endif
     {
         return std::make_shared<details::_ExceptionHolder>(_ExceptionPtr, _SetExceptionAddressHint);
     }
@@ -2727,7 +3891,7 @@ private:
         _TaskList _Tasks;
         bool _Cancel = false;
         {
-            Concurrency::critical_section::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
+            details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
             _CONCRT_ASSERT(!_M_Impl->_M_fHasValue);
             if (!_M_Impl->_M_fIsCanceled)
             {
@@ -2763,9 +3927,10 @@ private:
     /// </summary>
     void _RegisterTask(const typename details::_Task_ptr<_ResultType>::_Type & _TaskParam)
     {
+        details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
+#if _MSC_VER < 1800
         _TaskParam->_SetScheduledEvent();
-        Concurrency::critical_section::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
-
+#endif
         //If an exception was already set on this event, then cancel the task with the stored exception.
         if (_M_Impl->_HasUserException())
         {
@@ -2773,7 +3938,11 @@ private:
         }
         else if (_M_Impl->_M_fHasValue)
         {
+#if _MSC_VER >= 1800
+            _TaskParam->_FinalizeAndRunContinuations(_M_Impl->_M_value.Get());
+#else
             _TaskParam->_FinalizeAndRunContinuations(_M_Impl->_M_value);
+#endif
         }
         else
         {
@@ -2819,6 +3988,15 @@ public:
     {
         return _M_unitEvent.set(details::_Unit_type());
     }
+#if _MSC_VER >= 1800
+
+    template<typename _E>
+    __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
+        bool set_exception(_E _Except) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas
+    {
+            return _M_unitEvent._Cancel(std::make_exception_ptr(_Except), _CAPTURE_CALLSTACK());
+    }
+#endif
 
     /// <summary>
     ///     Propagates an exception to all tasks associated with this event.
@@ -2830,9 +4008,13 @@ public:
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
         bool set_exception(std::exception_ptr _ExceptionPtr) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas
     {
-            // It is important that _ReturnAddress() evaluate to the instruction after the call instruction for set_exception.
+        // It is important that _ReturnAddress() evaluate to the instruction after the call instruction for set_exception.
+#if _MSC_VER >= 1800
+            return _M_unitEvent._Cancel(_ExceptionPtr, _CAPTURE_CALLSTACK());
+#else
             return _M_unitEvent._Cancel(_ExceptionPtr, _ReturnAddress());
-        }
+#endif
+    }
 
     /// <summary>
     ///     Cancel the task_completion_event. Any task created using this event will be marked as canceled if it has
@@ -2895,15 +4077,27 @@ namespace details
     //
     // Anything callable is fine
     template<typename _ReturnType, typename _Ty>
-    auto _IsValidTaskCtor(_Ty _Param, int, int, int, int) -> typename decltype(_Param(), std::true_type());
+    auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, int, int) -> typename decltype(_Param(), std::true_type());
 
-    // Anything that has GetResults is fine: this covers all async operations
+    // Anything callable with a task return value is fine
     template<typename _ReturnType, typename _Ty>
-    auto _IsValidTaskCtor(_Ty _Param, int, int, int, ...) -> typename decltype(_Param->GetResults(), std::true_type());
+    auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<task<_ReturnType>*>()), std::true_type());
+
+    // Anything callable with a return value is fine
+    template<typename _ReturnType, typename _Ty>
+    auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<_ReturnType*>()), std::true_type());
+
+    // Anything that has GetResults is fine: this covers AsyncAction*
+    template<typename _ReturnType, typename _Ty>
+    auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, ...) -> typename decltype(_Param->GetResults(), std::true_type());
+
+    // Anything that has GetResults(TResult_abi*) is fine: this covers AsyncOperation*
+    template<typename _ReturnType, typename _Ty>
+    auto _IsValidTaskCtor(_Ty _Param, int, int, int, ...) -> typename decltype(_Param->GetResults(stdx::declval<decltype(_GetUnwrappedType(stdx::declval<_Ty>()))*>()), std::true_type());
 
     // Allow parameters with set: this covers task_completion_event
     template<typename _ReturnType, typename _Ty>
-    auto _IsValidTaskCtor(_Ty _Param, int, int, ...) -> typename decltype(_Param.set(std::declval<_ReturnType>()), std::true_type());
+    auto _IsValidTaskCtor(_Ty _Param, int, int, ...) -> typename decltype(_Param.set(stdx::declval<_ReturnType>()), std::true_type());
 
     template<typename _ReturnType, typename _Ty>
     auto _IsValidTaskCtor(_Ty _Param, int, ...) -> typename decltype(_Param.set(), std::true_type());
@@ -2916,7 +4110,7 @@ namespace details
     void _ValidateTaskConstructorArgs(_Ty _Param)
     {
         (void)_Param;
-        static_assert(std::is_same<decltype(_IsValidTaskCtor<_ReturnType>(_Param, 0, 0, 0, 0)), std::true_type>::value,
+        static_assert(std::is_same<decltype(details::_IsValidTaskCtor<_ReturnType>(_Param, 0, 0, 0, 0, 0, 0, 0)), std::true_type>::value,
             "incorrect argument for task constructor; can be a callable object, an asynchronous operation, or a task_completion_event"
             );
         static_assert(!(std::is_same<_Ty, _ReturnType>::value && details::_IsIAsyncInfo<_Ty>::_Value),
@@ -2925,23 +4119,39 @@ namespace details
     // Helpers for create_async validation
     //
     // A parameter lambda taking no arguments is valid
-    template<typename _Ty>
-    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int) -> typename decltype(_Param(), std::true_type());
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, int, int) -> typename decltype(_Param(), std::true_type());
+
+    // A parameter lambda taking a result argument is valid
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<_ReturnType*>()), std::true_type());
 
     // A parameter lambda taking an cancellation_token argument is valid
-    template<typename _Ty>
-    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, ...) -> typename decltype(_Param(cancellation_token::none()), std::true_type());
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, ...) -> typename decltype(_Param(Concurrency::cancellation_token::none()), std::true_type());
+
+    // A parameter lambda taking an cancellation_token argument and a result argument is valid
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, ...) -> typename decltype(_Param(Concurrency::cancellation_token::none(), stdx::declval<_ReturnType*>()), std::true_type());
 
     // A parameter lambda taking a progress report argument is valid
-    template<typename _Ty>
-    static auto _IsValidCreateAsync(_Ty _Param, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType()), std::true_type());
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType()), std::true_type());
+
+    // A parameter lambda taking a progress report argument and a result argument is valid
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), stdx::declval<_ReturnType*>()), std::true_type());
 
     // A parameter lambda taking a progress report and a cancellation_token argument is valid
-    template<typename _Ty>
-    static auto _IsValidCreateAsync(_Ty _Param, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), cancellation_token::none()), std::true_type());
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), Concurrency::cancellation_token::none()), std::true_type());
+
+    // A parameter lambda taking a progress report and a cancellation_token argument and a result argument is valid
+    template<typename _ReturnType, typename _Ty>
+    static auto _IsValidCreateAsync(_Ty _Param, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), Concurrency::cancellation_token::none(), stdx::declval<_ReturnType*>()), std::true_type());
 
     // All else is invalid
-    template<typename _Ty>
+    template<typename _ReturnType, typename _Ty>
     static std::false_type _IsValidCreateAsync(_Ty _Param, ...);
 }
 
@@ -3009,6 +4219,10 @@ public:
     ///     object should be a type equivalent to <c>std::function&lt;X(void)&gt;</c>, where X can be a variable of type <c>result_type</c>,
     ///     <c>task&lt;result_type&gt;</c>, or a Windows::Foundation::IAsyncInfo in Windows Store apps.
     /// </param>
+    /// <param name="_Token">
+    ///     The cancellation token to associate with this task. A task created without a cancellation token cannot be canceled. It implicitly receives
+    ///     the token <c>cancellation_token::none()</c>.
+    /// </param>
     /// <remarks>
     ///     The default constructor for a <c>task</c> is only present in order to allow tasks to be used within containers.
     ///     A default constructed task cannot be used until you assign a valid task to it. Methods such as <c>get</c>, <c>wait</c> or <c>then</c>
@@ -3032,13 +4246,23 @@ public:
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
         explicit task(_Ty _Param)
     {
+#if _MSC_VER >= 1800
+            task_options _TaskOptions;
+#endif
             details::_ValidateTaskConstructorArgs<_ReturnType, _Ty>(_Param);
 
+#if _MSC_VER >= 1800
+            _CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler());
+#else
             _CreateImpl(Concurrency::cancellation_token::none()._GetImplValue());
+#endif
             // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor.
+#if _MSC_VER >= 1800
+            _SetTaskCreationCallstack(_CAPTURE_CALLSTACK());
+#else
             _SetTaskCreationAddressHint(_ReturnAddress());
-
-            _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param, 0));
+#endif
+            _TaskInitMaybeFunctor(_Param, details::_IsCallable<_ReturnType>(_Param, 0, 0, 0));
         }
 
     /// <summary>
@@ -3078,15 +4302,26 @@ public:
     /**/
     template<typename _Ty>
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
+#if _MSC_VER >= 1800
+        explicit task(_Ty _Param, const task_options &_TaskOptions)
+#else
         explicit task(_Ty _Param, Concurrency::cancellation_token _Token)
+#endif
     {
             details::_ValidateTaskConstructorArgs<_ReturnType, _Ty>(_Param);
 
+#if _MSC_VER >= 1800
+            _CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler());
+#else
             _CreateImpl(_Token._GetImplValue());
+#endif
             // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor.
+#if _MSC_VER >= 1800
+            _SetTaskCreationCallstack(details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : _CAPTURE_CALLSTACK());
+#else
             _SetTaskCreationAddressHint(_ReturnAddress());
-
-            _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param, 0));
+#endif
+            _TaskInitMaybeFunctor(_Param, details::_IsCallable<_ReturnType>(_Param, 0, 0, 0));
         }
 
     /// <summary>
@@ -3207,10 +4442,16 @@ public:
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
         auto then(const _Function& _Func) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
     {
+#if _MSC_VER >= 1800
+            task_options _TaskOptions;
+            details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
+            return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
+#else
             auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, nullptr, task_continuation_context::use_default());
             // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then.
             _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
             return _ContinuationTask;
+#endif
         }
 
     /// <summary>
@@ -3239,13 +4480,23 @@ public:
     /**/
     template<typename _Function>
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
+#if _MSC_VER >= 1800
+        auto then(const _Function& _Func, task_options _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
+#else
         auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
+#endif
     {
+#if _MSC_VER >= 1800
+            details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
+            return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
+#else
         auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, _CancellationToken._GetImplValue(), task_continuation_context::use_default());
         // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then.
         _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
         return _ContinuationTask;
+#endif
     }
+#if _MSC_VER < 1800
     /// <summary>
     ///     Adds a continuation task to this task.
     /// </summary>
@@ -3279,7 +4530,7 @@ public:
         _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
         return _ContinuationTask;
     }
-
+#endif
     /// <summary>
     ///     Adds a continuation task to this task.
     /// </summary>
@@ -3312,10 +4563,16 @@ public:
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
         auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
     {
+#if _MSC_VER >= 1800
+            task_options _TaskOptions(_CancellationToken, _ContinuationContext);
+            details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
+            return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
+#else
             auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, _CancellationToken._GetImplValue(), _ContinuationContext);
             // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then.
             _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
             return _ContinuationTask;
+#endif
         }
 
     /// <summary>
@@ -3363,7 +4620,42 @@ public:
 
         return _M_Impl->_GetResult();
     }
+#if _MSC_VER >= 1800
+    /// <summary>
+    ///     Determines if the task is completed.
+    /// </summary>
+    /// <returns>
+    ///     True if the task has completed, false otherwise.
+    /// </returns>
+    /// <remarks>
+    ///     The function returns true if the task is completed or canceled (with or without user exception).
+    /// </remarks>
+    bool is_done() const
+    {
+        if (!_M_Impl)
+        {
+            throw Concurrency::invalid_operation("is_done() cannot be called on a default constructed task.");
+        }
+
+        return _M_Impl->_IsDone();
+    }
+
+    /// <summary>
+    ///     Returns the scheduler for this task
+    /// </summary>
+    /// <returns>
+    ///     A pointer to the scheduler
+    /// </returns>
+    Concurrency::scheduler_ptr scheduler() const
+    {
+        if (!_M_Impl)
+        {
+            throw Concurrency::invalid_operation("scheduler() cannot be called on a default constructed task.");
+        }
 
+        return _M_Impl->_GetScheduler();
+    }
+#endif
     /// <summary>
     ///     Determines whether the task unwraps a Windows Runtime <c>IAsyncInfo</c> interface or is descended from such a task.
     /// </summary>
@@ -3407,13 +4699,25 @@ public:
     /// <summary>
     ///     Create an underlying task implementation.
     /// </summary>
+#if _MSC_VER >= 1800
+    void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler)
+#else
     void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct)
+#endif
     {
         _CONCRT_ASSERT(_Ct != nullptr);
+#if _MSC_VER >= 1800
+        _M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct, _Scheduler);
+#else
         _M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct);
+#endif
         if (_Ct != Concurrency::details::_CancellationTokenState::_None())
         {
+#if _MSC_VER >= 1800
+            _M_Impl->_RegisterCancellation(_M_Impl);
+#else
             _M_Impl->_RegisterCancellation();
+#endif
         }
     }
 
@@ -3454,22 +4758,39 @@ public:
     /// <summary>
     ///     Sets a field in the task impl to the return address for calls to the task constructors and the then method.
     /// </summary>
+#if _MSC_VER >= 1800
+    void _SetTaskCreationCallstack(const details::_TaskCreationCallstack &_callstack)
+    {
+        _GetImpl()->_SetTaskCreationCallstack(_callstack);
+    }
+#else
     void _SetTaskCreationAddressHint(void* _Address)
     {
         _GetImpl()->_SetTaskCreationAddressHint(_Address);
     }
-
+#endif
     /// <summary>
     ///     An internal version of then that takes additional flags and always execute the continuation inline by default.
     ///     When _ForceInline is set to false, continuations inlining will be limited to default _DefaultAutoInline.
     ///     This function is Used for runtime internal continuations only.
     /// </summary>
     template<typename _Function>
+#if _MSC_VER >= 1800
+    auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState,
+        details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
+    {
+        // inherit from antecedent
+        auto _Scheduler = _GetImpl()->_GetScheduler();
+
+        return _ThenImpl<_ReturnType, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Scheduler, _CAPTURE_CALLSTACK(), _InliningMode);
+    }
+#else
     auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, bool _Aggregating,
-        Concurrency::details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
+        details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
     {
         return _ThenImpl<_ReturnType, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Aggregating, _InliningMode);
     }
+#endif
 
 private:
     template <typename T> friend class task;
@@ -3480,7 +4801,7 @@ private:
     class _Init_func_transformer
     {
     public:
-        static auto _Perform(std::function<_RetType(void)> _Func) -> decltype(_Func)
+        static auto _Perform(std::function<HRESULT(_RetType*)> _Func) -> decltype(_Func)
         {
             return _Func;
         }
@@ -3490,7 +4811,7 @@ private:
     class _Init_func_transformer<void>
     {
     public:
-        static auto _Perform(std::function<void(void)> _Func) -> decltype(details::_MakeVoidToUnitFunc(_Func))
+        static auto _Perform(std::function<HRESULT(void)> _Func) -> decltype(details::_MakeVoidToUnitFunc(_Func))
         {
             return details::_MakeVoidToUnitFunc(_Func);
         }
@@ -3499,7 +4820,7 @@ private:
     // The task handle type used to construct an 'initial task' - a task with no dependents.
     template <typename _InternalReturnType, typename _Function, typename _TypeSelection>
     struct _InitialTaskHandle :
-        details::_PPLTaskHandle<_ReturnType, _InitialTaskHandle<_InternalReturnType, _Function, _TypeSelection>, Concurrency::details::_UnrealizedChore>
+        details::_PPLTaskHandle<_ReturnType, _InitialTaskHandle<_InternalReturnType, _Function, _TypeSelection>, details::_UnrealizedChore>
     {
         _Function _M_function;
         _InitialTaskHandle(const typename details::_Task_ptr<_ReturnType>::_Type & _TaskImpl, const _Function & _Function) : _M_function(_Function), _PPLTaskHandle(_TaskImpl)
@@ -3507,11 +4828,26 @@ private:
         }
         virtual ~_InitialTaskHandle() {}
 
+#if _MSC_VER >= 1800
+        template <typename _Func, typename _RetArg>
+        auto _LogWorkItemAndInvokeUserLambda(_Func && _func, _RetArg && _retArg) const -> decltype(_func(std::forward<_RetArg>(_retArg)))
+        {
+            details::_TaskWorkItemRAIILogger _LogWorkItem(this->_M_pTask->_M_taskEventLogger);
+            return _func(std::forward<_RetArg>(_retArg));
+        }
+#endif
+
         void _Perform() const
         {
             _Init(_TypeSelection());
         }
+#if _MSC_VER >= 1800
 
+        void _SyncCancelAndPropagateException() const
+        {
+            this->_M_pTask->_Cancel(true);
+        }
+#endif
         //
         // Overload 0: returns _InternalReturnType
         //
@@ -3519,20 +4855,46 @@ private:
         //
         void _Init(details::_TypeSelectorNoAsync) const
         {
-            _M_pTask->_FinalizeAndRunContinuations(_Init_func_transformer<_InternalReturnType>::_Perform(_M_function)());
+            _ReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Init_func_transformer<_InternalReturnType>::_Perform(_M_function), &retVal);
+#else
+            HRESULT hr = _Init_func_transformer<_InternalReturnType>::_Perform(_M_function)(&retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            _M_pTask->_FinalizeAndRunContinuations(retVal);
         }
 
         //
-        // Overload 1: returns IAsyncOperation<_InternalReturnType>^ (only under /ZW)
+        // Overload 1: returns IAsyncOperation<_InternalReturnType>*
         //                   or
         //             returns task<_InternalReturnType>
         //
         // This is task whose functor returns an async operation or a task which will be unwrapped for continuation
         // Depending on the output type, the right _AsyncInit gets invoked
         //
-        void _Init(details::_TypeSelectorAsyncOperationOrTask) const
+        void _Init(details::_TypeSelectorAsyncTask) const
+        {
+            task<_InternalReturnType> retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
+#else
+            HRESULT hr = _M_function(&retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, retVal);
+        }
+        void _Init(details::_TypeSelectorAsyncOperation) const
         {
-            details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, _M_function());
+            _ReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
+#else
+            HRESULT hr = _M_function(&retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask,
+                Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_InternalReturnType>>(retVal).Get());
         }
 
         //
@@ -3542,7 +4904,14 @@ private:
         //
         void _Init(details::_TypeSelectorAsyncAction) const
         {
-            details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(_M_function()));
+            _ReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
+#else
+            HRESULT hr = _M_function(&retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(retVal).Get());
         }
 
         //
@@ -3553,9 +4922,15 @@ private:
         void _Init(details::_TypeSelectorAsyncOperationWithProgress) const
         {
             typedef details::_GetProgressType<decltype(_M_function())>::_Value _ProgressType;
-
+            _ReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
+#else
+            HRESULT hr = _M_function(&retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask,
-                Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_InternalReturnType, _ProgressType>>(_M_function()));
+                Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_InternalReturnType, _ProgressType>>(retVal).Get());
         }
 
         //
@@ -3566,9 +4941,15 @@ private:
         void _Init(details::_TypeSelectorAsyncActionWithProgress) const
         {
             typedef details::_GetProgressType<decltype(_M_function())>::_Value _ProgressType;
-
+            _ReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
+#else
+            HRESULT hr = _M_function(&retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask,
-                Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(_M_function()));
+                Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(retVal).Get());
         }
     };
 
@@ -3580,7 +4961,7 @@ private:
     class _Continuation_func_transformer
     {
     public:
-        static auto _Perform(std::function<_OutType(_InpType)> _Func) -> decltype(_Func)
+        static auto _Perform(std::function<HRESULT(_InpType, _OutType*)> _Func) -> decltype(_Func)
         {
             return _Func;
         }
@@ -3590,7 +4971,7 @@ private:
     class _Continuation_func_transformer<void, _OutType>
     {
     public:
-        static auto _Perform(std::function<_OutType(void)> _Func) -> decltype(details::_MakeUnitToTFunc<_OutType>(_Func))
+        static auto _Perform(std::function<HRESULT(_OutType*)> _Func) -> decltype(details::_MakeUnitToTFunc<_OutType>(_Func))
         {
             return details::_MakeUnitToTFunc<_OutType>(_Func);
         }
@@ -3600,7 +4981,7 @@ private:
     class _Continuation_func_transformer<_InType, void>
     {
     public:
-        static auto _Perform(std::function<void(_InType)> _Func) -> decltype(details::_MakeTToUnitFunc<_InType>(_Func))
+        static auto _Perform(std::function<HRESULT(_InType)> _Func) -> decltype(details::_MakeTToUnitFunc<_InType>(_Func))
         {
             return details::_MakeTToUnitFunc<_InType>(_Func);
         }
@@ -3610,7 +4991,7 @@ private:
     class _Continuation_func_transformer<void, void>
     {
     public:
-        static auto _Perform(std::function<void(void)> _Func) -> decltype(details::_MakeUnitToUnitFunc(_Func))
+        static auto _Perform(std::function<HRESULT(void)> _Func) -> decltype(details::_MakeUnitToUnitFunc(_Func))
         {
             return details::_MakeUnitToUnitFunc(_Func);
         }
@@ -3630,8 +5011,16 @@ private:
 
         _ContinuationTaskHandle(const typename details::_Task_ptr<_ReturnType>::_Type & _AncestorImpl,
             const typename details::_Task_ptr<_NormalizedContinuationReturnType>::_Type & _ContinuationImpl,
-            const _Function & _Func, const task_continuation_context & _Context, Concurrency::details::_TaskInliningMode _InliningMode) :
+            const _Function & _Func, const task_continuation_context & _Context, details::_TaskInliningMode _InliningMode) :
+#if _MSC_VER >= 1800
+            details::_PPLTaskHandle<typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type,
+            _ContinuationTaskHandle<_InternalReturnType, _ContinuationReturnType, _Function, _IsTaskBased, _TypeSelection>, details::_ContinuationTaskHandleBase>
+            ::_PPLTaskHandle(_ContinuationImpl)
+            , _M_ancestorTaskImpl(_AncestorImpl)
+            , _M_function(_Func)
+#else
             _M_ancestorTaskImpl(_AncestorImpl), _PPLTaskHandle(_ContinuationImpl), _M_function(_Func)
+#endif
         {
             _M_isTaskBasedContinuation = _IsTaskBased::value;
             _M_continuationContext = _Context;
@@ -3641,11 +5030,38 @@ private:
 
         virtual ~_ContinuationTaskHandle() {}
 
+#if _MSC_VER >= 1800
+        template <typename _Func, typename _Arg, typename _RetArg>
+        auto _LogWorkItemAndInvokeUserLambda(_Func && _func, _Arg && _value, _RetArg && _retArg) const -> decltype(_func(std::forward<_Arg>(_value), std::forward<_RetArg>(_retArg)))
+        {
+            details::_TaskWorkItemRAIILogger _LogWorkItem(this->_M_pTask->_M_taskEventLogger);
+            return _func(std::forward<_Arg>(_value), std::forward<_RetArg>(_retArg));
+        }
+#endif
+
         void _Perform() const
         {
             _Continue(_IsTaskBased(), _TypeSelection());
         }
 
+#if _MSC_VER >= 1800
+        void _SyncCancelAndPropagateException() const
+        {
+            if (_M_ancestorTaskImpl->_HasUserException())
+            {
+                // If the ancestor encountered an exception, transfer the exception to the continuation
+                // This traverses down the tree to propagate the exception.
+                this->_M_pTask->_CancelWithExceptionHolder(_M_ancestorTaskImpl->_GetExceptionHolder(), true);
+            }
+            else
+            {
+                // If the ancestor was canceled, then your own execution should be canceled.
+                // This traverses down the tree to cancel it.
+                this->_M_pTask->_Cancel(true);
+            }
+        }
+#endif
+
         //
         // Overload 0-0: _InternalReturnType -> _TaskType
         //
@@ -3653,26 +5069,53 @@ private:
         //
         void _Continue(std::false_type, details::_TypeSelectorNoAsync) const
         {
-            _M_pTask->_FinalizeAndRunContinuations(_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult()));
+            _NormalizedContinuationReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
+#else
+            HRESULT hr =_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            _M_pTask->_FinalizeAndRunContinuations(retVal);
         }
 
         //
-        // Overload 0-1: _InternalReturnType -> IAsyncOperation<_TaskType>^ (only uder /ZW)
+        // Overload 0-1: _InternalReturnType -> IAsyncOperation<_TaskType>*
         //               or
         //               _InternalReturnType -> task<_TaskType>
         //
         // This is a straight task continuation which returns an async operation or a task which will be unwrapped for continuation
         // Depending on the output type, the right _AsyncInit gets invoked
         //
-        void _Continue(std::false_type, details::_TypeSelectorAsyncOperationOrTask) const
+        void _Continue(std::false_type, details::_TypeSelectorAsyncTask) const
         {
             typedef typename details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
-
+            _FuncOutputType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
+#else
+            HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
                 _M_pTask,
-                _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult())
+                retVal
                 );
         }
+        void _Continue(std::false_type, details::_TypeSelectorAsyncOperation) const
+        {
+            typedef typename details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
+            _FuncOutputType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
+#else
+            HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
+                _M_pTask,
+                Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_ContinuationReturnType>>(retVal).Get());
+        }
 
         //
         // Overload 0-2: _InternalReturnType -> IAsyncAction*
@@ -3682,11 +5125,17 @@ private:
         void _Continue(std::false_type, details::_TypeSelectorAsyncAction) const
         {
             typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
-
+            _FuncOutputType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
+#else
+            HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
                 _M_pTask,
                 Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(
-                _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult())));
+                retVal).Get());
         }
 
         //
@@ -3698,12 +5147,18 @@ private:
         {
             typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
 
-            auto _OpWithProgress = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult());
+            _FuncOutputType _OpWithProgress;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
+#else
+            HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
+#endif
             typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;
 
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
                 _M_pTask,
-                Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_ContinuationReturnType, _ProgressType>>(_OpWithProgress));
+                Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_ContinuationReturnType, _ProgressType>>(_OpWithProgress).Get());
         }
 
         //
@@ -3715,12 +5170,18 @@ private:
         {
             typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
 
-            auto _OpWithProgress = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult());
+            _FuncOutputType _OpWithProgress;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
+#else
+            HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
+#endif
             typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;
 
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
                 _M_pTask,
-                Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(_OpWithProgress));
+                Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(_OpWithProgress).Get());
         }
 
 
@@ -3734,7 +5195,14 @@ private:
             typedef task<_InternalReturnType> _FuncInputType;
             task<_InternalReturnType> _ResultTask;
             _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
-            _M_pTask->_FinalizeAndRunContinuations(_Continuation_func_transformer<_FuncInputType, _ContinuationReturnType>::_Perform(_M_function)(std::move(_ResultTask)));
+            _NormalizedContinuationReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_FuncInputType, _ContinuationReturnType>::_Perform(_M_function), std::move(_ResultTask), &retVal);
+#else
+            HRESULT hr = _Continuation_func_transformer<_FuncInputType, _ContinuationReturnType>::_Perform(_M_function)(std::move(_ResultTask), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            _M_pTask->_FinalizeAndRunContinuations(retVal);
         }
 
         //
@@ -3746,12 +5214,34 @@ private:
         // the task's result. It also returns an async operation or a task which will be unwrapped
         // for continuation
         //
-        void _Continue(std::true_type, details::_TypeSelectorAsyncOperationOrTask) const
+        void _Continue(std::true_type, details::_TypeSelectorAsyncTask) const
+        {
+            // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task.
+            task<_InternalReturnType> _ResultTask;
+            _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
+            _ContinuationReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
+#else
+            HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, retVal);
+        }
+        void _Continue(std::true_type, details::_TypeSelectorAsyncOperation) const
         {
             // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task.
             task<_InternalReturnType> _ResultTask;
             _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
-            details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, _M_function(std::move(_ResultTask)));
+            _ContinuationReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
+#else
+            HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
+            details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
+                Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_ContinuationReturnType>>(retVal));
         }
 
         //
@@ -3765,8 +5255,15 @@ private:
             // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task.
             task<_InternalReturnType> _ResultTask;
             _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
+            _ContinuationReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
+#else
+            HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
-                Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(_M_function(std::move(_ResultTask))));
+                Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(retVal));
         }
 
         //
@@ -3783,9 +5280,15 @@ private:
             _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
 
             typedef details::_GetProgressType<decltype(_M_function(_ResultTask))>::_Value _ProgressType;
-
+            _ContinuationReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
+#else
+            HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
-                Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_ContinuationReturnType, _ProgressType>>(_M_function(std::move(_ResultTask))));
+                Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_ContinuationReturnType, _ProgressType>>(retVal));
         }
 
         //
@@ -3802,9 +5305,15 @@ private:
             _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
 
             typedef details::_GetProgressType<decltype(_M_function(_ResultTask))>::_Value _ProgressType;
-
+            _ContinuationReturnType retVal;
+#if _MSC_VER >= 1800
+            HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
+#else
+            HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
+#endif
+            if (FAILED(hr)) throw std::make_exception_ptr(hr);
             details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
-                Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(_M_function(std::move(_ResultTask))));
+                Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(retVal));
         }
     };
     /// <summary>
@@ -3813,11 +5322,13 @@ private:
     template<typename _InternalReturnType, typename _Function>
     void _TaskInitWithFunctor(const _Function& _Func)
     {
-        typedef details::_InitFunctorTypeTraits<_InternalReturnType, decltype(_Func())> _Async_type_traits;
+        typedef details::_InitFunctorTypeTraits<_InternalReturnType, details::_FunctionTypeTraits<_Function, void>::_FuncRetType> _Async_type_traits;
 
         _M_Impl->_M_fFromAsync = _Async_type_traits::_IsAsyncTask;
         _M_Impl->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync;
-
+#if _MSC_VER >= 1800
+        _M_Impl->_M_taskEventLogger._LogScheduleTask(false);
+#endif
         _M_Impl->_ScheduleTask(new _InitialTaskHandle<_InternalReturnType, _Function, typename _Async_type_traits::_AsyncKind>(_GetImpl(), _Func), Concurrency::details::_NoInline);
     }
 
@@ -3828,30 +5339,17 @@ private:
     {
         _Event._RegisterTask(_M_Impl);
     }
-    /// <summary>
-    ///     Initializes a task using an asynchronous action IAsyncAction*
-    /// </summary>
-    void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncAction* _AsyncAction)
-    {
-        _TaskInitAsyncOp((ABI::Windows::Foundation::IAsyncOperation<details::_Unit_type>*)Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(_AsyncAction).Detach());
-    }
 
     /// <summary>
-    ///     Initializes a task using an asynchronous action with progress IAsyncActionWithProgress<_P>*
-    /// </summary>
-    template<typename _P>
-    void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncActionWithProgress<_P>* _AsyncActionWithProgress)
-    {
-        _TaskInitAsyncOp(Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_P>>(_AsyncActionWithProgress).Detach());
-    }
-    /// <summary>
     ///     Initializes a task using an asynchronous operation IAsyncOperation<T>*
     /// </summary>
-    template<typename _Result>
-    void _TaskInitAsyncOp(ABI::Windows::Foundation::IAsyncOperation<_Result>* _AsyncOp)
+    template<typename _Result, typename _OpType, typename _CompHandlerType, typename _ResultType>
+    void _TaskInitAsyncOp(details::_AsyncInfoImpl<_OpType, _CompHandlerType, _ResultType>* _AsyncOp)
     {
         _M_Impl->_M_fFromAsync = true;
+#if _MSC_VER < 1800
         _M_Impl->_SetScheduledEvent();
+#endif
         // Mark this task as started here since we can set the state in the constructor without acquiring a lock. Once _AsyncInit
         // returns a completion could execute concurrently and the task must be fully initialized before that happens.
         _M_Impl->_M_TaskState = details::_Task_impl_base::_Started;
@@ -3865,7 +5363,7 @@ private:
     template<typename _Result>
     void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncOperation<_Result>* _AsyncOp)
     {
-        _TaskInitAsyncOp(_AsyncOp);
+        _TaskInitAsyncOp<_Result>(Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_Result>>(_AsyncOp).Get());
     }
 
     /// <summary>
@@ -3874,7 +5372,7 @@ private:
     template<typename _Result, typename _Progress>
     void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>* _AsyncOp)
     {
-        _TaskInitAsyncOp(Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_Result, _Progress>>(_AsyncOp).Detach());
+        _TaskInitAsyncOp<_Result>(Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_Result, _Progress>>(_AsyncOp).Get());
     }
     /// <summary>
     ///     Initializes a task using a callable object.
@@ -3893,13 +5391,32 @@ private:
     {
         _TaskInitNoFunctor(_Param);
     }
+#if _MSC_VER >= 1800
+    template<typename _InternalReturnType, typename _Function>
+    auto _ThenImpl(const _Function& _Func, const task_options& _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
+    {
+        if (!_M_Impl)
+        {
+            throw Concurrency::invalid_operation("then() cannot be called on a default constructed task.");
+        }
 
+        Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
+        auto _Scheduler = _TaskOptions.has_scheduler() ? _TaskOptions.get_scheduler() : _GetImpl()->_GetScheduler();
+        auto _CreationStack = details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : details::_TaskCreationCallstack();
+        return _ThenImpl<_InternalReturnType, _Function>(_Func, _PTokenState, _TaskOptions.get_continuation_context(), _Scheduler, _CreationStack);
+    }
+#endif
     /// <summary>
     ///     The one and only implementation of then for void and non-void tasks.
     /// </summary>
     template<typename _InternalReturnType, typename _Function>
+#if _MSC_VER >= 1800
+    auto _ThenImpl(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext, Concurrency::scheduler_ptr _Scheduler, details::_TaskCreationCallstack _CreationStack,
+        details::_TaskInliningMode _InliningMode = Concurrency::details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
+#else
     auto _ThenImpl(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext,
-        bool _Aggregating = false, Concurrency::details::_TaskInliningMode _InliningMode = Concurrency::details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
+        bool _Aggregating = false, details::_TaskInliningMode _InliningMode = Concurrency::details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
+#endif
     {
         if (_M_Impl == nullptr)
         {
@@ -3917,7 +5434,11 @@ private:
         //
         if (_PTokenState == nullptr)
         {
+#if _MSC_VER >= 1800
+            if (_Function_type_traits::_Takes_task::value)
+#else
             if (_Function_type_traits::_Takes_task())
+#endif
             {
                 _PTokenState = Concurrency::details::_CancellationTokenState::_None();
             }
@@ -3928,12 +5449,19 @@ private:
         }
 
         task<_TaskType> _ContinuationTask;
+#if _MSC_VER >= 1800
+        _ContinuationTask._CreateImpl(_PTokenState, _Scheduler);
+#else
         _ContinuationTask._CreateImpl(_PTokenState);
-
+#endif
         _ContinuationTask._GetImpl()->_M_fFromAsync = (_GetImpl()->_M_fFromAsync || _Async_type_traits::_IsAsyncTask);
+#if _MSC_VER < 1800
         _ContinuationTask._GetImpl()->_M_fRuntimeAggregate = _Aggregating;
+#endif
         _ContinuationTask._GetImpl()->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync;
-
+#if _MSC_VER >= 1800
+        _ContinuationTask._SetTaskCreationCallstack(_CreationStack);
+#endif
         _GetImpl()->_ScheduleContinuation(new _ContinuationTaskHandle<_InternalReturnType, _TaskType, _Function, typename _Function_type_traits::_Takes_task, typename _Async_type_traits::_AsyncKind>(
             _GetImpl(), _ContinuationTask._GetImpl(), _Func, _ContinuationContext, _InliningMode));
 
@@ -3960,6 +5488,12 @@ class task<void>
 {
 public:
     /// <summary>
+    ///     The type of the result an object of this class produces.
+    /// </summary>
+    /**/
+    typedef void result_type;
+
+    /// <summary>
     ///     Constructs a <c>task</c> object.
     /// </summary>
     /// <remarks>
@@ -3986,7 +5520,7 @@ public:
         // The default constructor should create a task with a nullptr impl. This is a signal that the
         // task is not usable and should throw if any wait(), get() or then() APIs are used.
     }
-
+#if _MSC_VER < 1800
     /// <summary>
     ///     Constructs a <c>task</c> object.
     /// </summary>
@@ -4028,9 +5562,9 @@ public:
         // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor.
         _M_unitTask._SetTaskCreationAddressHint(_ReturnAddress());
 
-        _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param, 0));
+        _TaskInitMaybeFunctor(_Param, details::_IsCallable<void>(_Param, 0, 0, 0));
     }
-
+#endif
     /// <summary>
     ///     Constructs a <c>task</c> object.
     /// </summary>
@@ -4068,15 +5602,25 @@ public:
     /**/
     template<typename _Ty>
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
+#if _MSC_VER >= 1800
+        explicit task(_Ty _Param, const task_options& _TaskOptions = task_options())
+#else
         explicit task(_Ty _Param, Concurrency::cancellation_token _CancellationToken)
+#endif
     {
             details::_ValidateTaskConstructorArgs<void, _Ty>(_Param);
-
+#if _MSC_VER >= 1800
+            _M_unitTask._CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler());
+#else
             _M_unitTask._CreateImpl(_CancellationToken._GetImplValue());
+#endif
             // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor.
+#if _MSC_VER >= 1800
+            _M_unitTask._SetTaskCreationCallstack(details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : _CAPTURE_CALLSTACK());
+#else
             _M_unitTask._SetTaskCreationAddressHint(_ReturnAddress());
-
-            _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param, 0));
+#endif
+            _TaskInitMaybeFunctor(_Param, details::_IsCallable<void>(_Param, 0, 0, 0));
         }
 
     /// <summary>
@@ -4172,6 +5716,7 @@ public:
         }
         return *this;
     }
+#if _MSC_VER < 1800
     /// <summary>
     ///     Adds a continuation task to this task.
     /// </summary>
@@ -4201,6 +5746,7 @@ public:
         _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
         return _ContinuationTask;
     }
+#endif
     /// <summary>
     ///     Adds a continuation task to this task.
     /// </summary>
@@ -4227,7 +5773,14 @@ public:
     /**/
     template<typename _Function>
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
-        auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
+#if _MSC_VER >= 1800
+    auto then(const _Function& _Func, task_options _TaskOptions = task_options()) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
+    {
+        details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
+        return _M_unitTask._ThenImpl<void, _Function>(_Func, _TaskOptions);
+    }
+#else
+    auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
     {
         auto _ContinuationTask = _M_unitTask._ThenImpl<void, _Function>(_Func, _CancellationToken._GetImplValue(), task_continuation_context::use_default());
         // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then.
@@ -4268,6 +5821,7 @@ public:
         return _ContinuationTask;
 
     }
+#endif
     /// <summary>
     ///     Adds a continuation task to this task.
     /// </summary>
@@ -4298,13 +5852,22 @@ public:
     /**/
     template<typename _Function>
     __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
-        auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
+#if _MSC_VER >= 1800
+    auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
     {
-            auto _ContinuationTask = _M_unitTask._ThenImpl<void, _Function>(_Func, _CancellationToken._GetImplValue(), _ContinuationContext);
-            // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then.
-            _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
-            return _ContinuationTask;
-        }
+        task_options _TaskOptions(_CancellationToken, _ContinuationContext);
+        details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
+        return _M_unitTask._ThenImpl<void, _Function>(_Func, _TaskOptions);
+    }
+#else
+    auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
+    {
+        auto _ContinuationTask = _M_unitTask._ThenImpl<void, _Function>(_Func, _CancellationToken._GetImplValue(), _ContinuationContext);
+        // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then.
+        _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
+        return _ContinuationTask;
+    }
+#endif
 
     /// <summary>
     ///     Waits for this task to reach a terminal state. It is possible for <c>wait</c> to execute the task inline, if all of the tasks
@@ -4333,8 +5896,34 @@ public:
     {
         _M_unitTask.get();
     }
+#if _MSC_VER >= 1800
+
+    /// <summary>
+    ///     Determines if the task is completed.
+    /// </summary>
+    /// <returns>
+    ///     True if the task has completed, false otherwise.
+    /// </returns>
+    /// <remarks>
+    ///     The function returns true if the task is completed or canceled (with or without user exception).
+    /// </remarks>
+    bool is_done() const
+    {
+        return _M_unitTask.is_done();
+    }
 
     /// <summary>
+    ///     Returns the scheduler for this task
+    /// </summary>
+    /// <returns>
+    ///     A pointer to the scheduler
+    /// </returns>
+    Concurrency::scheduler_ptr scheduler() const
+    {
+        return _M_unitTask.scheduler();
+    }
+#endif
+    /// <summary>
     ///     Determines whether the task unwraps a Windows Runtime <c>IAsyncInfo</c> interface or is descended from such a task.
     /// </summary>
     /// <returns>
@@ -4373,10 +5962,17 @@ public:
     /// <summary>
     ///     Create an underlying task implementation.
     /// </summary>
+#if _MSC_VER >= 1800
+    void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler)
+    {
+        _M_unitTask._CreateImpl(_Ct, _Scheduler);
+    }
+#else
     void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct)
     {
         _M_unitTask._CreateImpl(_Ct);
     }
+#endif
 
     /// <summary>
     ///     Return the underlying implementation for this task.
@@ -4413,20 +6009,38 @@ public:
     /// <summary>
     ///     Sets a field in the task impl to the return address for calls to the task constructors and the then method.
     /// </summary>
+#if _MSC_VER >= 1800
+    void _SetTaskCreationCallstack(const details::_TaskCreationCallstack &_callstack)
+    {
+        _M_unitTask._SetTaskCreationCallstack(_callstack);
+    }
+#else
     void _SetTaskCreationAddressHint(void* _Address)
     {
         _M_unitTask._SetTaskCreationAddressHint(_Address);
     }
+#endif
 
     /// <summary>
     ///     An internal version of then that takes additional flags and executes the continuation inline. Used for runtime internal continuations only.
     /// </summary>
     template<typename _Function>
+#if _MSC_VER >= 1800
+    auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState,
+        details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
+    {
+        // inherit from antecedent
+        auto _Scheduler = _GetImpl()->_GetScheduler();
+
+        return _M_unitTask._ThenImpl<void, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Scheduler, _CAPTURE_CALLSTACK(), _InliningMode);
+    }
+#else
     auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState,
-        bool _Aggregating, Concurrency::details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
+        bool _Aggregating, details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
     {
         return _M_unitTask._ThenImpl<void, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Aggregating, _InliningMode);
     }
+#endif
 
 private:
     template <typename T> friend class task;
@@ -4440,6 +6054,22 @@ private:
         _M_unitTask._TaskInitNoFunctor(_Event._M_unitEvent);
     }
     /// <summary>
+    ///     Initializes a task using an asynchronous action IAsyncAction*
+    /// </summary>
+    void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncAction* _AsyncAction)
+    {
+        _M_unitTask._TaskInitAsyncOp<details::_Unit_type>(Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(_AsyncAction).Get());
+    }
+
+    /// <summary>
+    ///     Initializes a task using an asynchronous action with progress IAsyncActionWithProgress<_P>*
+    /// </summary>
+    template<typename _P>
+    void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncActionWithProgress<_P>* _AsyncActionWithProgress)
+    {
+        _M_unitTask._TaskInitAsyncOp<details::_Unit_type>(Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_P>>(_AsyncActionWithProgress).Get());
+    }
+    /// <summary>
     ///     Initializes a task using a callable object.
     /// </summary>
     template<typename _Function>
@@ -4468,18 +6098,6 @@ namespace details
     ///   The following type traits are used for the create_task function.
     /// </summary>
 
-    // Unwrap functions for asyncOperations
-    template<typename _Ty>
-    HRESULT _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperation<_Ty>*);
-
-    HRESULT _GetUnwrappedType(ABI::Windows::Foundation::IAsyncAction*);
-
-    template<typename _Ty, typename _Progress>
-    HRESULT _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Ty, _Progress>*);
-
-    template<typename _Progress>
-    HRESULT _GetUnwrappedType(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>*);
-
     // Unwrap task<T>
     template<typename _Ty>
     _Ty _GetUnwrappedType(task<_Ty>);
@@ -4507,22 +6125,22 @@ namespace details
 
     // Callable
     template<typename _Ty>
-    auto _GetTaskType(_Ty _Func, std::true_type) -> decltype(_GetUnwrappedReturnType(_Func(), 0));
+    auto _GetTaskType(_Ty _Func, std::true_type) -> decltype(_GetUnwrappedReturnType(stdx::declval<_FunctionTypeTraits<_Ty, void>::_FuncRetType>(), 0));
 
     // Special callable returns void
-    void _GetTaskType(std::function<void()>, std::true_type);
+    void _GetTaskType(std::function<HRESULT()>, std::true_type);
     struct _BadArgType{};
 
-    template<typename _Ty>
-    auto _FilterValidTaskType(_Ty _Param, int) -> decltype(_GetTaskType(_Param, _IsCallable(_Param, 0)));
+    template<typename _ReturnType, typename _Ty>
+    auto _FilterValidTaskType(_Ty _Param, int) -> decltype(_GetTaskType(_Param, _IsCallable<_ReturnType>(_Param, 0, 0, 0)));
 
-    template<typename _Ty>
+    template<typename _ReturnType, typename _Ty>
     _BadArgType _FilterValidTaskType(_Ty _Param, ...);
 
-    template<typename _Ty>
+    template<typename _ReturnType, typename _Ty>
     struct _TaskTypeFromParam
     {
-        typedef decltype(_FilterValidTaskType(std::declval<_Ty>(), 0)) _Type;
+        typedef decltype(_FilterValidTaskType<_ReturnType>(stdx::declval<_Ty>(), 0)) _Type;
     };
 }
 
@@ -4555,19 +6173,27 @@ namespace details
 /// <seealso cref="task Class"/>
 /// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
 /**/
-template<typename _Ty>
+template<typename _ReturnType, typename _Ty>
 __declspec(noinline)
-auto create_task(_Ty _Param) -> task<typename details::_TaskTypeFromParam<_Ty>::_Type>
+#if _MSC_VER >= 1800
+auto create_task(_Ty _Param, task_options _TaskOptions = task_options()) -> task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type>
+#else
+auto create_task(_Ty _Param) -> task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type>
+#endif
 {
-    static_assert(!std::is_same<typename details::_TaskTypeFromParam<_Ty>::_Type, details::_BadArgType>::value,
+    static_assert(!std::is_same<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type, details::_BadArgType>::value,
         "incorrect argument for create_task; can be a callable object, an asynchronous operation, or a task_completion_event"
         );
-
-    task<typename details::_TaskTypeFromParam<_Ty>::_Type> _CreatedTask(_Param);
+#if _MSC_VER >= 1800
+    details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
+    task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type> _CreatedTask(_Param, _TaskOptions);
+#else
+    task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type> _CreatedTask(_Param);
     // Ideally we would like to forceinline create_task, but __forceinline does nothing on debug builds. Therefore, we ask for no inlining
     // and overwrite the creation address hint set by the task constructor. DO NOT REMOVE this next line from create_task. It is
     // essential that _ReturnAddress() evaluate to the instruction right after the call to create_task in client code.
     _CreatedTask._SetTaskCreationAddressHint(_ReturnAddress());
+#endif
     return _CreatedTask;
 }
 
@@ -4602,44 +6228,54 @@ auto create_task(_Ty _Param) -> task<typename details::_TaskTypeFromParam<_Ty>::
 /// <seealso cref="task Class"/>
 /// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
 /**/
-template<typename _Ty>
+#if _MSC_VER >= 1800
+template<typename _ReturnType>
+__declspec(noinline)
+task<_ReturnType> create_task(const task<_ReturnType>& _Task)
+{
+    task<_ReturnType> _CreatedTask(_Task);
+    return _CreatedTask;
+}
+#else
+template<typename _ReturnType, typename _Ty>
 __declspec(noinline)
-auto create_task(_Ty _Param, Concurrency::cancellation_token _Token) -> task<typename details::_TaskTypeFromParam<_Ty>::_Type>
+auto create_task(_Ty _Param, Concurrency::cancellation_token _Token) -> task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type>
 {
-    static_assert(!std::is_same<typename details::_TaskTypeFromParam<_Ty>::_Type, details::_BadArgType>::value,
+    static_assert(!std::is_same<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type, details::_BadArgType>::value,
         "incorrect argument for create_task; can be a callable object, an asynchronous operation, or a task_completion_event"
         );
-    task<typename details::_TaskTypeFromParam<_Ty>::_Type> _CreatedTask(_Param, _Token);
+    task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type> _CreatedTask(_Param, _Token);
     // Ideally we would like to forceinline create_task, but __forceinline does nothing on debug builds. Therefore, we ask for no inlining
     // and overwrite the creation address hint set by the task constructor. DO NOT REMOVE this next line from create_task. It is
     // essential that _ReturnAddress() evaluate to the instruction right after the call to create_task in client code.
     _CreatedTask._SetTaskCreationAddressHint(_ReturnAddress());
     return _CreatedTask;
 }
+#endif
 
 namespace details
 {
     template<typename _T>
-    task<HRESULT> _To_task_helper(ABI::Windows::Foundation::IAsyncOperation<_T>* op)
+    task<typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_T>*>()))>::type> _To_task_helper(ABI::Windows::Foundation::IAsyncOperation<_T>* op)
     {
-        return task<HRESULT>(op);
+        return task<_T>(op);
     }
 
     template<typename _T, typename _Progress>
-    task<HRESULT> _To_task_helper(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T, _Progress>* op)
+    task<typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_T, _Progress>*>()))>::type> _To_task_helper(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T, _Progress>* op)
     {
-        return task<HRESULT>(op);
+        return task<_T>(op);
     }
 
-    inline task<HRESULT> _To_task_helper(ABI::Windows::Foundation::IAsyncAction* op)
+    inline task<void> _To_task_helper(ABI::Windows::Foundation::IAsyncAction* op)
     {
-        return task<HRESULT>(op);
+        return task<void>(op);
     }
 
     template<typename _Progress>
-    task<HRESULT> _To_task_helper(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>* op)
+    task<void> _To_task_helper(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>* op)
     {
-        return task<HRESULT>(op);
+        return task<void>(op);
     }
 
     template<typename _ProgressType>
@@ -4660,1669 +6296,3164 @@ namespace details
     public:
 
         virtual ~_ProgressDispatcher()
-        {
-        }
-
-        _ProgressDispatcher(_ClassPtrType _Ptr) : _M_ptr(_Ptr)
-        {
-        }
-
-        virtual void _Report(const _ProgressType& _Val)
-        {
-            _M_ptr->_FireProgress(_Val);
-        }
-
-    private:
-
-        _ClassPtrType _M_ptr;
-    };
-} // namespace details
-
-
-/// <summary>
-///     The progress reporter class allows reporting progress notifications of a specific type. Each progress_reporter object is bound
-///     to a particular asynchronous action or operation.
-/// </summary>
-/// <typeparam name="_ProgressType">
-///     The payload type of each progress notification reported through the progress reporter.
-/// </typeparam>
-/// <remarks>
-///     This type is only available to Windows Store apps.
-/// </remarks>
-/// <seealso cref="create_async Function"/>
-/**/
-template<typename _ProgressType>
-class progress_reporter
-{
-    typedef std::shared_ptr<details::_ProgressDispatcherBase<_ProgressType>> _PtrType;
-
-public:
-
-    /// <summary>
-    ///     Sends a progress report to the asynchronous action or operation to which this progress reporter is bound.
-    /// </summary>
-    /// <param name="_Val">
-    ///     The payload to report through a progress notification.
-    /// </param>
-    /**/
-    void report(const _ProgressType& _Val) const
-    {
-        _M_dispatcher->_Report(_Val);
-    }
-
-    template<typename _ClassPtrType>
-    static progress_reporter _CreateReporter(_ClassPtrType _Ptr)
-    {
-        progress_reporter _Reporter;
-        details::_ProgressDispatcherBase<_ProgressType> *_PDispatcher = new details::_ProgressDispatcher<_ProgressType, _ClassPtrType>(_Ptr);
-        _Reporter._M_dispatcher = _PtrType(_PDispatcher);
-        return _Reporter;
-    }
-    progress_reporter() {}
-
-private:
-    progress_reporter(details::_ProgressReporterCtorArgType);
-
-    _PtrType _M_dispatcher;
-};
-
-namespace details
-{
-    //
-    // maps internal definitions for AsyncStatus and defines states that are not client visible
-    //
-    enum _AsyncStatusInternal
-    {
-        _AsyncCreated = -1,  // externally invisible
-        // client visible states (must match AsyncStatus exactly)
-        _AsyncStarted = ABI::Windows::Foundation::AsyncStatus::Started, // 0
-        _AsyncCompleted = ABI::Windows::Foundation::AsyncStatus::Completed, // 1
-        _AsyncCanceled = ABI::Windows::Foundation::AsyncStatus::Canceled, // 2
-        _AsyncError = ABI::Windows::Foundation::AsyncStatus::Error, // 3
-        // non-client visible internal states
-        _AsyncCancelPending,
-        _AsyncClosed,
-        _AsyncUndefined
-    };
-
-    //
-    // designates whether the "GetResults" method returns a single result (after complete fires) or multiple results
-    // (which are progressively consumable between Start state and before Close is called)
-    //
-    enum _AsyncResultType
-    {
-        SingleResult = 0x0001,
-        MultipleResults = 0x0002
-    };
-
-    // ***************************************************************************
-    // Template type traits and helpers for async production APIs:
-    //
-
-    struct _ZeroArgumentFunctor { };
-    struct _OneArgumentFunctor { };
-    struct _TwoArgumentFunctor { };
-    struct _ThreeArgumentFunctor { };
-
-    // ****************************************
-    // CLASS TYPES:
-
-    // ********************
-    // THREE ARGUMENTS:
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg3 _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
-
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
-
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
-
-    // ********************
-    // TWO ARGUMENTS:
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
-    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
-
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
-    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
-
-    template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
-    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
-
-    // ********************
-    // ONE ARGUMENT:
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1>
-    _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1>
-    void _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
-
-    // non-void arg:
-    template<typename _Class, typename _ReturnType, typename _Arg1>
-    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
-
-    template<typename _Class, typename _ReturnType, typename _Arg1>
-    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
-
-    template<typename _Class, typename _ReturnType, typename _Arg1>
-    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1) const);
+        {
+        }
 
-    // ********************
-    // ZERO ARGUMENT:
+        _ProgressDispatcher(_ClassPtrType _Ptr) : _M_ptr(_Ptr)
+        {
+        }
 
-    // void arg:
-    template<typename _Class, typename _ReturnType>
-    void _Arg1ClassHelperThunk(_ReturnType(_Class::*)() const);
+        virtual void _Report(const _ProgressType& _Val)
+        {
+            _M_ptr->_FireProgress(_Val);
+        }
 
-    // void arg:
-    template<typename _Class, typename _ReturnType>
-    void _Arg2ClassHelperThunk(_ReturnType(_Class::*)() const);
+    private:
 
-    // void arg:
-    template<typename _Class, typename _ReturnType>
-    void _Arg3ClassHelperThunk(_ReturnType(_Class::*)() const);
+        _ClassPtrType _M_ptr;
+    };
+} // namespace details
 
-    // void arg:
-    template<typename _Class, typename _ReturnType>
-    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)() const);
 
-    template<typename _Class, typename _ReturnType>
-    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)() const);
+/// <summary>
+///     The progress reporter class allows reporting progress notifications of a specific type. Each progress_reporter object is bound
+///     to a particular asynchronous action or operation.
+/// </summary>
+/// <typeparam name="_ProgressType">
+///     The payload type of each progress notification reported through the progress reporter.
+/// </typeparam>
+/// <remarks>
+///     This type is only available to Windows Store apps.
+/// </remarks>
+/// <seealso cref="create_async Function"/>
+/**/
+template<typename _ProgressType>
+class progress_reporter
+{
+    typedef std::shared_ptr<details::_ProgressDispatcherBase<_ProgressType>> _PtrType;
 
-    // ****************************************
-    // POINTER TYPES:
+public:
 
-    // ********************
-    // THREE ARGUMENTS:
+    /// <summary>
+    ///     Sends a progress report to the asynchronous action or operation to which this progress reporter is bound.
+    /// </summary>
+    /// <param name="_Val">
+    ///     The payload to report through a progress notification.
+    /// </param>
+    /**/
+    void report(const _ProgressType& _Val) const
+    {
+        _M_dispatcher->_Report(_Val);
+    }
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+    template<typename _ClassPtrType>
+    static progress_reporter _CreateReporter(_ClassPtrType _Ptr)
+    {
+        progress_reporter _Reporter;
+        details::_ProgressDispatcherBase<_ProgressType> *_PDispatcher = new details::_ProgressDispatcher<_ProgressType, _ClassPtrType>(_Ptr);
+        _Reporter._M_dispatcher = _PtrType(_PDispatcher);
+        return _Reporter;
+    }
+    progress_reporter() {}
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+private:
+    progress_reporter(details::_ProgressReporterCtorArgType);
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg3 _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+    _PtrType _M_dispatcher;
+};
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+namespace details
+{
+    //
+    // maps internal definitions for AsyncStatus and defines states that are not client visible
+    //
+    enum _AsyncStatusInternal
+    {
+        _AsyncCreated = -1,  // externally invisible
+        // client visible states (must match AsyncStatus exactly)
+        _AsyncStarted = ABI::Windows::Foundation::AsyncStatus::Started, // 0
+        _AsyncCompleted = ABI::Windows::Foundation::AsyncStatus::Completed, // 1
+        _AsyncCanceled = ABI::Windows::Foundation::AsyncStatus::Canceled, // 2
+        _AsyncError = ABI::Windows::Foundation::AsyncStatus::Error, // 3
+        // non-client visible internal states
+        _AsyncCancelPending,
+        _AsyncClosed,
+        _AsyncUndefined
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
+    //
+    // designates whether the "GetResults" method returns a single result (after complete fires) or multiple results
+    // (which are progressively consumable between Start state and before Close is called)
+    //
+    enum _AsyncResultType
+    {
+        SingleResult = 0x0001,
+        MultipleResults = 0x0002
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+    template<typename _T>
+    struct _ProgressTypeTraits
+    {
+        static const bool _TakesProgress = false;
+        typedef void _ProgressType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+    template<typename _T>
+    struct _ProgressTypeTraits<progress_reporter<_T>>
+    {
+        static const bool _TakesProgress = true;
+        typedef typename _T _ProgressType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg3 _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+    template<typename _T, bool bTakesToken = std::is_same<_T, Concurrency::cancellation_token>::value, bool bTakesProgress = _ProgressTypeTraits<_T>::_TakesProgress>
+    struct _TokenTypeTraits
+    {
+        static const bool _TakesToken = false;
+        typedef typename _T _ReturnType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+    template<typename _T>
+    struct _TokenTypeTraits<_T, false, true>
+    {
+        static const bool _TakesToken = false;
+        typedef void _ReturnType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
+    template<typename _T>
+    struct _TokenTypeTraits<_T, true, false>
+    {
+        static const bool _TakesToken = true;
+        typedef void _ReturnType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+    template<typename _T, size_t count = _FunctorTypeTraits<_T>::_ArgumentCount>
+    struct _CAFunctorOptions
+    {
+        static const bool _TakesProgress = false;
+        static const bool _TakesToken = false;
+        typedef void _ProgressType;
+        typedef void _ReturnType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+    template<typename _T>
+    struct _CAFunctorOptions<_T, 1>
+    {
+    private:
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _Arg3 _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+        typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+    public:
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
-    _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
+        static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress;
+        static const bool _TakesToken = _TokenTypeTraits<_Argument1Type>::_TakesToken;
+        typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
+        typedef typename _TokenTypeTraits<_Argument1Type>::_ReturnType _ReturnType;
+    };
 
-    // ********************
-    // TWO ARGUMENTS:
+    template<typename _T>
+    struct _CAFunctorOptions<_T, 2>
+    {
+    private:
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+        typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
+        typedef typename _FunctorTypeTraits<_T>::_Argument2Type _Argument2Type;
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+    public:
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+        static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress;
+        static const bool _TakesToken = !_TakesProgress ? true : _TokenTypeTraits<_Argument2Type>::_TakesToken;
+        typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
+        typedef typename _TokenTypeTraits<_Argument2Type>::_ReturnType _ReturnType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+    template<typename _T>
+    struct _CAFunctorOptions<_T, 3>
+    {
+    private:
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2));
+        typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+    public:
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+        static const bool _TakesProgress = true;
+        static const bool _TakesToken = true;
+        typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
+        typedef typename _FunctorTypeTraits<_T>::_Argument3Type _ReturnType;
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+    class _Zip
+    {
+    };
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+    // ***************************************************************************
+    // Async Operation Task Generators
+    //
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2));
+    //
+    // Functor returns an IAsyncInfo - result needs to be wrapped in a task:
+    //
+    template<typename _AsyncSelector, typename _ReturnType>
+    struct _SelectorTaskGenerator
+    {
+#if _MSC_VER >= 1800
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>(_Func(_pRet), _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>(_Func(_Cts.get_token(), _pRet), _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>(_Func(_Progress, _pRet), _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>(_Func(_Progress, _Cts.get_token(), _pRet), _taskOptinos);
+        }
+#else
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>(_Func(_pRet), _Cts.get_token());
+        }
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>(_Func(_Cts.get_token(), _pRet), _Cts.get_token());
+        }
 
-    template<typename _ReturnType, typename _Arg1, typename _Arg2>
-    _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2));
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>(_Func(_Progress, _pRet), _Cts.get_token());
+        }
 
-    // ********************
-    // ONE ARGUMENT:
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>(_Func(_Progress, _Cts.get_token(), _pRet), _Cts.get_token());
+        }
+#endif
+    };
 
-    template<typename _ReturnType, typename _Arg1>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+    template<typename _AsyncSelector>
+    struct _SelectorTaskGenerator<_AsyncSelector, void>
+    {
+#if _MSC_VER >= 1800
+        template<typename _Function>
+        static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>(_Func(), _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+        template<typename _Function>
+        static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>(_Func(_Cts.get_token()), _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>(_Func(_Progress), _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>(_Func(_Progress, _Cts.get_token()), _taskOptinos);
+        }
+#else
+        template<typename _Function>
+        static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>(_Func(), _Cts.get_token());
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1));
+        template<typename _Function>
+        static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>(_Func(_Cts.get_token()), _Cts.get_token());
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>(_Func(_Progress), _Cts.get_token());
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>(_Func(_Progress, _Cts.get_token()), _Cts.get_token());
+        }
+#endif
+    };
 
-    template<typename _ReturnType, typename _Arg1>
-    void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+#if _MSC_VER < 1800
+    // For create_async lambdas that return a (non-task) result, we oversubscriber the current task for the duration of the
+    // lambda.
+    struct _Task_generator_oversubscriber
+    {
+        _Task_generator_oversubscriber()
+        {
+            Concurrency::details::_Context::_Oversubscribe(true);
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
+        ~_Task_generator_oversubscriber()
+        {
+            Concurrency::details::_Context::_Oversubscribe(false);
+        }
+    };
+#endif
 
-    template<typename _ReturnType, typename _Arg1>
-    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1));
+    //
+    // Functor returns a result - it needs to be wrapped in a task:
+    //
+    template<typename _ReturnType>
+    struct _SelectorTaskGenerator<details::_TypeSelectorNoAsync, _ReturnType>
+    {
+#if _MSC_VER >= 1800
 
-    template<typename _ReturnType, typename _Arg1>
-    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+#pragma warning(push)
+#pragma warning(disable: 4702)
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                HRESULT hr = _Func(_pRet);
+                retVal = _pRet;
+                return hr;
+            }, _taskOptinos);
+        }
+#pragma warning(pop)
 
-    template<typename _ReturnType, typename _Arg1>
-    void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                HRESULT hr = _Func(_Cts.get_token(), _pRet);
+                retVal = _pRet;
+                return hr;
+            }, _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                HRESULT hr = _Func(_Progress, _pRet);
+                retVal = _pRet;
+                return hr;
+            }, _taskOptinos);
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                HRESULT hr = _Func(_Progress, _Cts.get_token(), _pRet);
+                retVal = _pRet;
+                return hr;
+            }, _taskOptinos);
+        }
+#else
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                HRESULT hr = _Func(_pRet);
+                retVal = _pRet;
+                return hr;
+            }, _Cts.get_token());
+        }
 
-    template<typename _ReturnType, typename _Arg1>
-    _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1));
+        template<typename _Function>
+        static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                HRESULT hr = _Func(_Cts.get_token(), _pRet);
+                retVal = _pRet;
+                return hr;
+            }, _Cts.get_token());
+        }
 
-    // ********************
-    // ZERO ARGUMENT:
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                HRESULT hr = _Func(_Progress, _pRet);
+                retVal = _pRet;
+                return hr;
+            }, _Cts.get_token());
+        }
 
-    template<typename _ReturnType>
-    void _Arg1PFNHelperThunk(_ReturnType(__cdecl *)());
+        template<typename _Function, typename _ProgressObject>
+        static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                HRESULT hr = _Func(_Progress, _Cts.get_token(), _pRet);
+                retVal = _pRet;
+                return hr;
+            }, _Cts.get_token());
+        }
+#endif
+    };
 
-    template<typename _ReturnType>
-    void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)());
+    template<>
+    struct _SelectorTaskGenerator<details::_TypeSelectorNoAsync, void>
+    {
+#if _MSC_VER >= 1800
+        template<typename _Function>
+        static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>([=]() -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                return _Func();
+            }, _taskOptinos);
+        }
 
-    template<typename _ReturnType>
-    void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)());
+        template<typename _Function>
+        static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>([=]() -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                return _Func(_Cts.get_token());
+            }, _taskOptinos);
+        }
 
-    template<typename _ReturnType>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)());
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>([=]() -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                return _Func(_Progress);
+            }, _taskOptinos);
+        }
 
-    template<typename _ReturnType>
-    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)());
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            task_options _taskOptinos(_Cts.get_token());
+            details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
+            return task<void>([=]() -> HRESULT {
+                Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
+                (_Oversubscriber);
+                return _Func(_Progress, _Cts.get_token());
+            }, _taskOptinos);
+        }
+#else
+        template<typename _Function>
+        static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>([=]() -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                return _Func();
+            }, _Cts.get_token());
+        }
 
-    template<typename _ReturnType>
-    void _Arg1PFNHelperThunk(_ReturnType(__stdcall *)());
+        template<typename _Function>
+        static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>([=]() -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                return _Func(_Cts.get_token());
+            }, _Cts.get_token());
+        }
 
-    template<typename _ReturnType>
-    void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)());
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>([=]() -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                return _Func(_Progress);
+            }, _Cts.get_token());
+        }
 
-    template<typename _ReturnType>
-    void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)());
+        template<typename _Function, typename _ProgressObject>
+        static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        {
+            return task<void>([=]() -> HRESULT {
+                _Task_generator_oversubscriber _Oversubscriber;
+                return _Func(_Progress, _Cts.get_token());
+            }, _Cts.get_token());
+        }
+#endif
+    };
 
+    //
+    // Functor returns a task - the task can directly be returned:
+    //
     template<typename _ReturnType>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)());
+    struct _SelectorTaskGenerator<details::_TypeSelectorAsyncTask, _ReturnType>
+    {
+        template<typename _Function>
+#if _MSC_VER >= 1800
+        static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+#else
+        static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+#endif
+        {
+            task<_ReturnType> _task;
+            _Func(&_task);
+            return _task;
+        }
 
-    template<typename _ReturnType>
-    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)());
+        template<typename _Function>
+#if _MSC_VER >= 1800
+        static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+#else
+        static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+#endif
+        {
+            task<_ReturnType> _task;
+            _Func(_Cts.get_token(), &_task);
+            return _task;
+        }
 
-    template<typename _ReturnType>
-    void _Arg1PFNHelperThunk(_ReturnType(__fastcall *)());
+        template<typename _Function, typename _ProgressObject>
+#if _MSC_VER >= 1800
+        static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+#else
+        static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+#endif
+        {
+            task<_ReturnType> _task;
+            _Func(_Progress, &_task);
+            return _task;
+        }
 
-    template<typename _ReturnType>
-    void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)());
+        template<typename _Function, typename _ProgressObject>
+#if _MSC_VER >= 1800
+        static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+#else
+        static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+#endif
+        {
+            task<_ReturnType> _task;
+            _Func(_Progress, _Cts.get_token(), &_task);
+            return _task;
+        }
+    };
 
-    template<typename _ReturnType>
-    void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)());
+    template<>
+    struct _SelectorTaskGenerator<details::_TypeSelectorAsyncTask, void>
+    {
+        template<typename _Function>
+#if _MSC_VER >= 1800
+        static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+#else
+        static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+#endif
+        {
+            task<void> _task;
+            _Func(&_task);
+            return _task;
+        }
 
-    template<typename _ReturnType>
-    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)());
+        template<typename _Function>
+#if _MSC_VER >= 1800
+        static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+#else
+        static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+#endif
+        {
+            task<void> _task;
+            _Func(_Cts.get_token(), &_task);
+            return _task;
+        }
 
-    template<typename _ReturnType>
-    _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)());
+        template<typename _Function, typename _ProgressObject>
+#if _MSC_VER >= 1800
+        static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+#else
+        static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+#endif
+        {
+            task<void> _task;
+            _Func(_Progress, &_task);
+            return _task;
+        }
 
-    template<typename _T>
-    struct _FunctorArguments
-    {
-        static const size_t _Count = 0;
+        template<typename _Function, typename _ProgressObject>
+#if _MSC_VER >= 1800
+        static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+#else
+        static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+#endif
+        {
+            task<void> _task;
+            _Func(_Progress, _Cts.get_token(), &_task);
+            return _task;
+        }
     };
 
-    template<>
-    struct _FunctorArguments<_OneArgumentFunctor>
+    template<typename _Generator, bool _TakesToken, bool TakesProgress>
+    struct _TaskGenerator
     {
-        static const size_t _Count = 1;
     };
 
-    template<>
-    struct _FunctorArguments<_TwoArgumentFunctor>
+    template<typename _Generator>
+    struct _TaskGenerator<_Generator, false, false>
     {
-        static const size_t _Count = 2;
+#if _MSC_VER >= 1800
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
+        {
+            (void)_Ptr;
+            return _Generator::_GenerateTask_0(_Func, _Cts, _callstack);
+        }
+
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
+        {
+            return _Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack);
+        }
+#else
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
+        {
+            (void)_Ptr;
+            return _Generator::_GenerateTask_0(_Func, _Cts);
+        }
+
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
+        {
+            return _Generator::_GenerateTask_0(_Func, _Cts, _pRet);
+        }
+#endif
     };
 
-    template<>
-    struct _FunctorArguments<_ThreeArgumentFunctor>
+    template<typename _Generator>
+    struct _TaskGenerator<_Generator, true, false>
     {
-        static const size_t _Count = 3;
+#if _MSC_VER >= 1800
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
+        {
+            return _Generator::_GenerateTask_1C(_Func, _Cts, _callstack);
+        }
+
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
+        {
+            return _Generator::_GenerateTask_1C(_Func, _Cts, _pRet, _callstack);
+        }
+#else
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
+        {
+            return _Generator::_GenerateTask_1C(_Func, _Cts);
+        }
+
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
+        {
+            return _Generator::_GenerateTask_1C(_Func, _Cts, _pRet);
+        }
+#endif
     };
 
-    template<typename _T>
-    struct _FunctorTypeTraits
+    template<typename _Generator>
+    struct _TaskGenerator<_Generator, false, true>
     {
-        typedef decltype(_ArgumentCountHelper(&(_T::operator()))) _ArgumentCountType;
-        static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count;
+#if _MSC_VER >= 1800
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
+        {
+            return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _callstack);
+        }
 
-        typedef decltype(_ReturnTypeClassHelperThunk(&(_T::operator()))) _ReturnType;
-        typedef decltype(_Arg1ClassHelperThunk(&(_T::operator()))) _Argument1Type;
-        typedef decltype(_Arg2ClassHelperThunk(&(_T::operator()))) _Argument2Type;
-        typedef decltype(_Arg3ClassHelperThunk(&(_T::operator()))) _Argument3Type;
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
+        {
+            return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet, _callstack);
+        }
+#else
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
+        {
+            return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts);
+        }
+
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
+        {
+            return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet);
+        }
+#endif
     };
 
-    template<typename _T>
-    struct _FunctorTypeTraits<_T *>
+    template<typename _Generator>
+    struct _TaskGenerator<_Generator, true, true>
     {
-        typedef decltype(_ArgumentCountHelper(std::declval<_T*>())) _ArgumentCountType;
-        static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count;
+#if _MSC_VER >= 1800
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
+        {
+            return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _callstack);
+        }
+
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
+        {
+            return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet, _callstack);
+        }
+#else
+        template<typename _Function, typename _ClassPtr, typename _ProgressType>
+        static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
+        {
+            return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts);
+        }
 
-        typedef decltype(_ReturnTypePFNHelperThunk(std::declval<_T*>())) _ReturnType;
-        typedef decltype(_Arg1PFNHelperThunk(std::declval<_T*>())) _Argument1Type;
-        typedef decltype(_Arg2PFNHelperThunk(std::declval<_T*>())) _Argument2Type;
-        typedef decltype(_Arg3PFNHelperThunk(std::declval<_T*>())) _Argument3Type;
+        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
+        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
+        {
+            return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet);
+        }
+#endif
     };
 
-    template<typename _T>
-    struct _ProgressTypeTraits
+    // ***************************************************************************
+    // Async Operation Attributes Classes
+    //
+    // These classes are passed through the hierarchy of async base classes in order to hold multiple attributes of a given async construct in
+    // a single container. An attribute class must define:
+    //
+    // Mandatory:
+    // -------------------------
+    //
+    // _AsyncBaseType           : The Windows Runtime interface which is being implemented.
+    // _CompletionDelegateType  : The Windows Runtime completion delegate type for the interface.
+    // _ProgressDelegateType    : If _TakesProgress is true, the Windows Runtime progress delegate type for the interface. If it is false, an empty Windows Runtime type.
+    // _ReturnType              : The return type of the async construct (void for actions / non-void for operations)
+    //
+    // _TakesProgress           : An indication as to whether or not
+    //
+    // _Generate_Task           : A function adapting the user's function into what's necessary to produce the appropriate task
+    //
+    // Optional:
+    // -------------------------
+    //
+
+    template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken, bool _TakesProgress>
+    struct _AsyncAttributes
     {
-        static const bool _TakesProgress = false;
-        typedef void _ProgressType;
     };
 
-    template<typename _T>
-    struct _ProgressTypeTraits<progress_reporter<_T>>
+    template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken>
+    struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, true>
     {
+        typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgress<_ReturnType, _ProgressType> _AsyncBaseType;
+        typedef typename ABI::Windows::Foundation::IAsyncOperationProgressHandler<_ReturnType, _ProgressType> _ProgressDelegateType;
+        typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_ReturnType, _ProgressType> _CompletionDelegateType;
+        typedef typename _ReturnType _ReturnType;
+        typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<_AsyncBaseType*>()))>::type _ReturnType_abi;
+        typedef typename _ProgressType _ProgressType;
+        typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressProgressSelector(stdx::declval<_AsyncBaseType*>()))>::type _ProgressType_abi;
+        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
+        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
+        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator;
+
         static const bool _TakesProgress = true;
-        typedef typename _T _ProgressType;
-    };
+        static const bool _TakesToken = _TakesToken;
 
-    template<typename _T, bool bTakesToken = std::is_same<_T, Concurrency::cancellation_token_source>::value>
-    struct _TokenTypeTraits
-    {
-        static const bool _TakesToken = false;
-        typedef typename _T _ReturnType;
+        template<typename _Function, typename _ClassPtr>
+#if _MSC_VER >= 1800
+        static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi, _ReturnType>(_Func, _Ptr, _Cts, _pRet, _callstack);
+        }
+#else
+        static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi, _ReturnType>(_Func, _Ptr, _Cts, _pRet);
+        }
+#endif
     };
 
-    template<typename _T>
-    struct _TokenTypeTraits<_T, true>
+    template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken>
+    struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, false>
     {
-        static const bool _TakesToken = true;
-        typedef void _ReturnType;
-    };
+        typedef typename ABI::Windows::Foundation::IAsyncOperation<_ReturnType> _AsyncBaseType;
+        typedef _Zip _ProgressDelegateType;
+        typedef typename ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_ReturnType> _CompletionDelegateType;
+        typedef typename _ReturnType _ReturnType;
+        typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<_AsyncBaseType*>()))>::type _ReturnType_abi;
+        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
+        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
+        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator;
 
-    template<typename _T, size_t count = _FunctorTypeTraits<_T>::_ArgumentCount>
-    struct _CAFunctorOptions
-    {
         static const bool _TakesProgress = false;
-        static const bool _TakesToken = false;
-        typedef void _ProgressType;
-        typedef void _ReturnType;
+        static const bool _TakesToken = _TakesToken;
+
+        template<typename _Function, typename _ClassPtr>
+#if _MSC_VER >= 1800
+        static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet, _callstack);
+        }
+#else
+        static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet);
+        }
+#endif
     };
 
-    template<typename _T>
-    struct _CAFunctorOptions<_T, 1>
+    template<typename _Function, typename _ProgressType, typename _TaskTraits, bool _TakesToken>
+    struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, true>
     {
-    private:
-
-        typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
+        typedef typename ABI::Windows::Foundation::IAsyncActionWithProgress<_ProgressType> _AsyncBaseType;
+        typedef typename ABI::Windows::Foundation::IAsyncActionProgressHandler<_ProgressType> _ProgressDelegateType;
+        typedef typename ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_ProgressType> _CompletionDelegateType;
+        typedef void _ReturnType;
+        typedef void _ReturnType_abi;
+        typedef typename _ProgressType _ProgressType;
+        typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncActionWithProgressSelector(stdx::declval<_AsyncBaseType*>()))>::type _ProgressType_abi;
+        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
+        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
+        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator;
 
-    public:
+        static const bool _TakesProgress = true;
+        static const bool _TakesToken = _TakesToken;
 
-        static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress;
-        static const bool _TakesToken = _TokenTypeTraits<_Argument1Type>::_TakesToken;
-        typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
-        typedef typename _TokenTypeTraits<_Argument1Type>::_TakesToken::_ReturnType _ReturnType;
+#if _MSC_VER >= 1800
+        template<typename _Function, typename _ClassPtr>
+        static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _callstack);
+        }
+        template<typename _Function, typename _ClassPtr>
+        static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _pRet, _callstack);
+        }
+#else
+        template<typename _Function, typename _ClassPtr>
+        static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+        {
+            return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts);
+        }
+        template<typename _Function, typename _ClassPtr>
+        static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _pRet);
+        }
+#endif
     };
 
-    template<typename _T>
-    struct _CAFunctorOptions<_T, 2>
+    template<typename _Function, typename _ProgressType, typename _TaskTraits, bool _TakesToken>
+    struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, false>
     {
-    private:
-
-        typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
-        typedef typename _FunctorTypeTraits<_T>::_Argument2Type _Argument2Type;
+        typedef typename ABI::Windows::Foundation::IAsyncAction _AsyncBaseType;
+        typedef _Zip _ProgressDelegateType;
+        typedef typename ABI::Windows::Foundation::IAsyncActionCompletedHandler _CompletionDelegateType;
+        typedef void _ReturnType;
+        typedef void _ReturnType_abi;
+        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
+        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
+        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator;
 
-    public:
+        static const bool _TakesProgress = false;
+        static const bool _TakesToken = _TakesToken;
 
-        static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress;
-        static const bool _TakesToken = !_TakesProgress ? true : _TokenTypeTraits<_Argument2Type>::_TakesToken;
-        typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
-        typedef typename _TokenTypeTraits<_Argument2Type>::_TakesToken::_ReturnType _ReturnType;
+#if _MSC_VER >= 1800
+        template<typename _Function, typename _ClassPtr>
+        static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
+        {
+            return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _callstack);
+        }
+        template<typename _Function, typename _ClassPtr>
+        static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _pRet, _callstack);
+        }
+#else
+        template<typename _Function, typename _ClassPtr>
+        static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+        {
+            return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts);
+        }
+        template<typename _Function, typename _ClassPtr>
+        static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        {
+            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _pRet);
+        }
+#endif
     };
 
-    template<typename _T>
-    struct _CAFunctorOptions<_T, 3>
+    template<typename _Function>
+    struct _AsyncLambdaTypeTraits
     {
-    private:
-
-        typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
-
-    public:
+        typedef typename _Unhat<typename _CAFunctorOptions<_Function>::_ReturnType>::_Value _ReturnType;
+        typedef typename _FunctorTypeTraits<_Function>::_Argument1Type _Argument1Type;
+        typedef typename _CAFunctorOptions<_Function>::_ProgressType _ProgressType;
 
-        static const bool _TakesProgress = true;
-        static const bool _TakesToken = true;
-        typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
-        typedef typename _FunctorTypeTraits<_T>::_Argument3Type _ReturnType;
-    };
+        static const bool _TakesProgress = _CAFunctorOptions<_Function>::_TakesProgress;
+        static const bool _TakesToken = _CAFunctorOptions<_Function>::_TakesToken;
 
-    class _Zip
-    {
+        typedef typename _TaskTypeTraits<_ReturnType> _TaskTraits;
+        typedef typename _AsyncAttributes<_Function, _ProgressType, typename _TaskTraits::_TaskRetType, _TaskTraits, _TakesToken, _TakesProgress> _AsyncAttributes;
     };
-
     // ***************************************************************************
-    // Async Operation Task Generators
+    // AsyncInfo (and completion) Layer:
     //
+#ifndef RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoBase_DEFINED
+#define RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoBase_DEFINED
+    extern const __declspec(selectany) WCHAR RuntimeClass_Concurrency_winrt_details__AsyncInfoBase[] = L"Concurrency_winrt.details._AsyncInfoBase";
+#endif
 
     //
-    // Functor returns an IAsyncInfo - result needs to be wrapped in a task:
+    // Internal base class implementation for async operations (based on internal Windows representation for ABI level async operations)
     //
-    template<typename _AsyncSelector, typename _ReturnType>
-    struct _SelectorTaskGenerator
+    template < typename _Attributes, _AsyncResultType resultType = SingleResult >
+    class _AsyncInfoBase abstract : public Microsoft::WRL::RuntimeClass<
+        Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>, Microsoft::WRL::Implements<typename _Attributes::_AsyncBaseType, ABI::Windows::Foundation::IAsyncInfo>>
     {
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        InspectableClass(RuntimeClass_Concurrency_winrt_details__AsyncInfoBase, BaseTrust)
+    public:
+        _AsyncInfoBase() :
+            _M_currentStatus(_AsyncStatusInternal::_AsyncCreated),
+            _M_errorCode(S_OK),
+            _M_completeDelegate(nullptr),
+            _M_CompleteDelegateAssigned(0),
+            _M_CallbackMade(0)
         {
-            return task<HRESULT>(_Func(_pRet), _Cts.get_token());
+#if _MSC_VER < 1800
+            _M_id = Concurrency::details::_GetNextAsyncId();
+#else
+            _M_id = Concurrency::details::platform::GetNextAsyncId();
+#endif
         }
-
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+    public:
+        virtual STDMETHODIMP GetResults(typename _Attributes::_ReturnType_abi* results)
         {
-            return task<HRESULT>(_Func(_Cts.get_token(), _pRet), _Cts.get_token());
+            (void)results;
+            return E_UNEXPECTED;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP get_Id(unsigned int* id)
         {
-            return task<HRESULT>(_Func(_Progress, _pRet), _Cts.get_token());
+            HRESULT hr = _CheckValidStateForAsyncInfoCall();
+            if (FAILED(hr)) return hr;
+            if (!id) return E_POINTER;
+            *id = _M_id;
+            return S_OK;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP put_Id(unsigned int id)
         {
-            return task<HRESULT>(_Func(_Progress, _Cts.get_token(), _pRet), _Cts.get_token());
-        }
-    };
+            HRESULT hr = _CheckValidStateForAsyncInfoCall();
+            if (FAILED(hr)) return hr;
 
-    template<typename _AsyncSelector>
-    struct _SelectorTaskGenerator<_AsyncSelector, void>
-    {
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
-        {
-            return task<HRESULT>(_Func(), _Cts.get_token());
-        }
+            if (id == 0)
+            {
+                return E_INVALIDARG;
+            }
+            else if (_M_currentStatus != _AsyncStatusInternal::_AsyncCreated)
+            {
+                return E_ILLEGAL_METHOD_CALL;
+            }
 
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
-        {
-            return task<HRESULT>(_Func(_Cts.get_token()), _Cts.get_token());
+            _M_id = id;
+            return S_OK;
         }
-
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        virtual STDMETHODIMP get_Status(ABI::Windows::Foundation::AsyncStatus* status)
         {
-            return task<HRESULT>(_Func(_Progress), _Cts.get_token());
-        }
+            HRESULT hr = _CheckValidStateForAsyncInfoCall();
+            if (FAILED(hr)) return hr;
+            if (!status) return E_POINTER;
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
-        {
-            return task<HRESULT>(_Func(_Progress, _Cts.get_token()), _Cts.get_token());
-        }
-    };
+            _AsyncStatusInternal _Current = _M_currentStatus;
+            //
+            // Map our internal cancel pending to cancelled. This way "pending cancelled" looks to the outside as "cancelled" but
+            // can still transition to "completed" if the operation completes without acknowledging the cancellation request
+            //
+            switch (_Current)
+            {
+            case _AsyncCancelPending:
+                _Current = _AsyncCanceled;
+                break;
+            case _AsyncCreated:
+                _Current = _AsyncStarted;
+                break;
+            default:
+                break;
+            }
 
-    // For create_async lambdas that return a (non-task) result, we oversubscriber the current task for the duration of the
-    // lambda.
-    struct _Task_generator_oversubscriber
-    {
-        _Task_generator_oversubscriber()
-        {
-            Concurrency::details::_Context::_Oversubscribe(true);
+            *status = static_cast<ABI::Windows::Foundation::AsyncStatus>(_Current);
+            return S_OK;
         }
 
-        ~_Task_generator_oversubscriber()
+        virtual STDMETHODIMP get_ErrorCode(HRESULT* errorCode)
         {
-            Concurrency::details::_Context::_Oversubscribe(false);
+            HRESULT hr = _CheckValidStateForAsyncInfoCall();
+            if (FAILED(hr)) return hr;
+            if (!hr) return hr;
+            *errorCode = _M_errorCode;
+            return S_OK;
         }
-    };
-
-    //
-    // Functor returns a result - it needs to be wrapped in a task:
-    //
-    template<typename _ReturnType>
-    struct _SelectorTaskGenerator<details::_TypeSelectorNoAsync, _ReturnType>
-    {
 
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP get_Progress(typename _Attributes::_ProgressDelegateType** _ProgressHandler)
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func(_pRet);
-            }, _Cts.get_token());
+            return _GetOnProgress(_ProgressHandler);
         }
 
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP put_Progress(typename _Attributes::_ProgressDelegateType* _ProgressHandler)
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func(_Cts.get_token(), _pRet);
-            }, _Cts.get_token());
+            return _PutOnProgress(_ProgressHandler);
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP Cancel()
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func(_Progress, _pRet);
-            }, _Cts.get_token());
+            if (_TransitionToState(_AsyncCancelPending))
+            {
+                _OnCancel();
+            }
+            return S_OK;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP Close()
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func(_Progress, _Cts.get_token(), _pRet);
-            }, _Cts.get_token());
+            if (_TransitionToState(_AsyncClosed))
+            {
+                _OnClose();
+            }
+            else
+            {
+                if (_M_currentStatus != _AsyncClosed) // Closed => Closed transition is just ignored
+                {
+                    return E_ILLEGAL_STATE_CHANGE;
+                }
+            }
+            return S_OK;
         }
-    };
 
-    template<>
-    struct _SelectorTaskGenerator<details::_TypeSelectorNoAsync, void>
-    {
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        virtual STDMETHODIMP get_Completed(typename _Attributes::_CompletionDelegateType** _CompleteHandler)
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func();
-            }, _Cts.get_token());
+            _CheckValidStateForDelegateCall();
+            if (!_CompleteHandler) return E_POINTER;
+            *_CompleteHandler = _M_completeDelegate.Get();
+            return S_OK;
         }
 
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        virtual STDMETHODIMP put_Completed(typename _Attributes::_CompletionDelegateType* _CompleteHandler)
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func(_Cts.get_token());
-            }, _Cts.get_token());
+            _CheckValidStateForDelegateCall();
+            // this delegate property is "write once"
+            if (InterlockedIncrement(&_M_CompleteDelegateAssigned) == 1)
+            {
+                _M_completeDelegateContext = _ContextCallback::_CaptureCurrent();
+                _M_completeDelegate = _CompleteHandler;
+                // Guarantee that the write of _M_completeDelegate is ordered with respect to the read of state below
+                // as perceived from _FireCompletion on another thread.
+                MemoryBarrier();
+                if (_IsTerminalState())
+                {
+                    _FireCompletion();
+                }
+            }
+            else
+            {
+                return E_ILLEGAL_DELEGATE_ASSIGNMENT;
+            }
+            return S_OK;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+    protected:
+        // _Start - this is not externally visible since async operations "hot start" before returning to the caller
+        STDMETHODIMP _Start()
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func(_Progress);
-            }, _Cts.get_token());
+            if (_TransitionToState(_AsyncStarted))
+            {
+                _OnStart();
+            }
+            else
+            {
+                return E_ILLEGAL_STATE_CHANGE;
+            }
+            return S_OK;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        HRESULT _FireCompletion()
         {
-            return task<HRESULT>([=]() -> HRESULT {
-                _Task_generator_oversubscriber _Oversubscriber;
-                return _Func(_Progress, _Cts.get_token());
-            }, _Cts.get_token());
+            HRESULT hr = S_OK;
+            _TryTransitionToCompleted();
+
+            // we guarantee that completion can only ever be fired once
+            if (_M_completeDelegate != nullptr && InterlockedIncrement(&_M_CallbackMade) == 1)
+            {
+                hr = _M_completeDelegateContext._CallInContext([=]() -> HRESULT {
+                    ABI::Windows::Foundation::AsyncStatus status;
+                    HRESULT hr;
+                    if (SUCCEEDED(hr = this->get_Status(&status)))
+                        _M_completeDelegate->Invoke((_Attributes::_AsyncBaseType*)this, status);
+                    _M_completeDelegate = nullptr;
+                    return hr;
+                });
+            }
+            return hr;
         }
-    };
 
-    //
-    // Functor returns a task - the task can directly be returned:
-    //
-    template<typename _ReturnType>
-    struct _SelectorTaskGenerator<details::_TypeSelectorAsyncTask, _ReturnType>
-    {
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler)
         {
-            return _Func(_pRet);
+            (void)_ProgressHandler;
+            return E_UNEXPECTED;
         }
 
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler)
         {
-            return _Func(_Cts.get_token(), _pRet);
+            (void)_ProgressHandler;
+            return E_UNEXPECTED;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+
+        bool _TryTransitionToCompleted()
         {
-            return _Func(_Progress, _pRet);
+            return _TransitionToState(_AsyncStatusInternal::_AsyncCompleted);
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        bool _TryTransitionToCancelled()
         {
-            return _Func(_Progress, _Cts.get_token(), _pRet);
+            return _TransitionToState(_AsyncStatusInternal::_AsyncCanceled);
         }
-    };
 
-    template<>
-    struct _SelectorTaskGenerator<details::_TypeSelectorAsyncTask, void>
-    {
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        bool _TryTransitionToError(const HRESULT error)
         {
-            return _Func();
+            _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_errorCode), error, S_OK);
+            return _TransitionToState(_AsyncStatusInternal::_AsyncError);
         }
 
-        template<typename _Function>
-        static task<HRESULT> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
+        // This method checks to see if the delegate properties can be
+        // modified in the current state and generates the appropriate
+        // error hr in the case of violation.
+        inline HRESULT _CheckValidStateForDelegateCall()
         {
-            return _Func(_Cts.get_token());
+            if (_M_currentStatus == _AsyncClosed)
+            {
+                return E_ILLEGAL_METHOD_CALL;
+            }
+            return S_OK;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        // This method checks to see if results can be collected in the
+        // current state and generates the appropriate error hr in
+        // the case of a violation.
+        inline HRESULT _CheckValidStateForResultsCall()
         {
-            return _Func(_Progress);
+            _AsyncStatusInternal _Current = _M_currentStatus;
+
+            if (_Current == _AsyncError)
+            {
+                return _M_errorCode;
+            }
+#pragma warning(push)
+#pragma warning(disable: 4127) // Conditional expression is constant
+            // single result illegal before transition to Completed or Cancelled state
+            if (resultType == SingleResult)
+#pragma warning(pop)
+            {
+                if (_Current != _AsyncCompleted)
+                {
+                    return E_ILLEGAL_METHOD_CALL;
+                }
+            }
+            // multiple results can be called after Start has been called and before/after Completed
+            else if (_Current != _AsyncStarted &&
+                _Current != _AsyncCancelPending &&
+                _Current != _AsyncCanceled &&
+                _Current != _AsyncCompleted)
+            {
+                return E_ILLEGAL_METHOD_CALL;
+            }
+            return S_OK;
         }
 
-        template<typename _Function, typename _ProgressObject>
-        static task<HRESULT> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
+        // This method can be called by derived classes periodically to determine
+        // whether the asynchronous operation should continue processing or should
+        // be halted.
+        inline bool _ContinueAsyncOperation()
         {
-            return _Func(_Progress, _Cts.get_token());
+            return _M_currentStatus == _AsyncStarted;
         }
-    };
 
-    template<typename _Generator, bool _TakesToken, bool TakesProgress>
-    struct _TaskGenerator
-    {
-    };
+        // These two methods are used to allow the async worker implementation do work on
+        // state transitions. No real "work" should be done in these methods. In other words
+        // they should not block for a long time on UI timescales.
+        virtual void _OnStart() = 0;
+        virtual void _OnClose() = 0;
+        virtual void _OnCancel() = 0;
 
-    template<typename _Generator>
-    struct _TaskGenerator<_Generator, false, false>
-    {
-        template<typename _Function, typename _ClassPtr, typename _ProgressType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
-        {
-            (void)_Ptr;
-            return _Generator::_GenerateTask_0(_Func, _Cts);
-        }
+    private:
 
-        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
+        // This method is used to check if calls to the AsyncInfo properties
+        // (id, status, errorcode) are legal in the current state. It also
+        // generates the appropriate error hr to return in the case of an
+        // illegal call.
+        inline HRESULT _CheckValidStateForAsyncInfoCall()
         {
-            return _Generator::_GenerateTask_0(_Func, _Cts, _pRet);
+            _AsyncStatusInternal _Current = _M_currentStatus;
+            if (_Current == _AsyncClosed)
+            {
+                return E_ILLEGAL_METHOD_CALL;
+            }
+            else if (_Current == _AsyncCreated)
+            {
+                return E_ASYNC_OPERATION_NOT_STARTED;
+            }
+            return S_OK;
         }
-    };
 
-    template<typename _Generator>
-    struct _TaskGenerator<_Generator, true, false>
-    {
-        template<typename _Function, typename _ClassPtr, typename _ProgressType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
+        inline bool _TransitionToState(const _AsyncStatusInternal _NewState)
         {
-            return _Generator::_GenerateTask_1C(_Func, _Cts);
-        }
+            _AsyncStatusInternal _Current = _M_currentStatus;
 
-        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
-        {
-            return _Generator::_GenerateTask_1C(_Func, _Cts, _pRet);
-        }
-    };
+            // This enforces the valid state transitions of the asynchronous worker object
+            // state machine.
+            switch (_NewState)
+            {
+            case _AsyncStatusInternal::_AsyncStarted:
+                if (_Current != _AsyncCreated)
+                {
+                    return false;
+                }
+                break;
+            case _AsyncStatusInternal::_AsyncCompleted:
+                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
+                {
+                    return false;
+                }
+                break;
+            case _AsyncStatusInternal::_AsyncCancelPending:
+                if (_Current != _AsyncStarted)
+                {
+                    return false;
+                }
+                break;
+            case _AsyncStatusInternal::_AsyncCanceled:
+                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
+                {
+                    return false;
+                }
+                break;
+            case _AsyncStatusInternal::_AsyncError:
+                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
+                {
+                    return false;
+                }
+                break;
+            case _AsyncStatusInternal::_AsyncClosed:
+                if (!_IsTerminalState(_Current))
+                {
+                    return false;
+                }
+                break;
+            default:
+                return false;
+                break;
+            }
 
-    template<typename _Generator>
-    struct _TaskGenerator<_Generator, false, true>
-    {
-        template<typename _Function, typename _ClassPtr, typename _ProgressType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
-        {
-            return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts);
-        }
+            // attempt the transition to the new state
+            // Note: if currentStatus_ == _Current, then there was no intervening write
+            // by the async work object and the swap succeeded.
+            _AsyncStatusInternal _RetState = static_cast<_AsyncStatusInternal>(
+                _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_currentStatus),
+                _NewState,
+                static_cast<LONG>(_Current)));
 
-        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
-        {
-            return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet);
+            // ICE returns the former state, if the returned state and the
+            // state we captured at the beginning of this method are the same,
+            // the swap succeeded.
+            return (_RetState == _Current);
         }
-    };
 
-    template<typename _Generator>
-    struct _TaskGenerator<_Generator, true, true>
-    {
-        template<typename _Function, typename _ClassPtr, typename _ProgressType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
+        inline bool _IsTerminalState()
         {
-            return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts);
+            return _IsTerminalState(_M_currentStatus);
         }
 
-        template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
-        static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-            -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
+        inline bool _IsTerminalState(_AsyncStatusInternal status)
         {
-            return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet);
+            return (status == _AsyncError ||
+                status == _AsyncCanceled ||
+                status == _AsyncCompleted ||
+                status == _AsyncClosed);
         }
-    };
-
-    // ***************************************************************************
-    // Async Operation Attributes Classes
-    //
-    // These classes are passed through the hierarchy of async base classes in order to hold multiple attributes of a given async construct in
-    // a single container. An attribute class must define:
-    //
-    // Mandatory:
-    // -------------------------
-    //
-    // _AsyncBaseType           : The Windows Runtime interface which is being implemented.
-    // _CompletionDelegateType  : The Windows Runtime completion delegate type for the interface.
-    // _ProgressDelegateType    : If _TakesProgress is true, the Windows Runtime progress delegate type for the interface. If it is false, an empty Windows Runtime type.
-    // _ReturnType              : The return type of the async construct (void for actions / non-void for operations)
-    //
-    // _TakesProgress           : An indication as to whether or not
-    //
-    // _Generate_Task           : A function adapting the user's function into what's necessary to produce the appropriate task
-    //
-    // Optional:
-    // -------------------------
-    //
 
-    template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken, bool _TakesProgress>
-    struct _AsyncAttributes
-    {
-    };
+    private:
 
-    template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken>
-    struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, true>
-    {
-        typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgress<_ReturnType, _ProgressType> _AsyncBaseType;
-        typedef typename ABI::Windows::Foundation::IAsyncOperationProgressHandler<_ReturnType, _ProgressType> _ProgressDelegateType;
-        typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_ReturnType, _ProgressType> _CompletionDelegateType;
-        typedef typename _ReturnType _ReturnType;
-        typedef typename _ProgressType _ProgressType;
-        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
-        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
-        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator;
+        _ContextCallback        _M_completeDelegateContext;
+        Microsoft::WRL::ComPtr<typename _Attributes::_CompletionDelegateType>  _M_completeDelegate; //ComPtr cannot be volatile as it does not have volatile accessors
+        _AsyncStatusInternal volatile                   _M_currentStatus;
+        HRESULT volatile                                _M_errorCode;
+        unsigned int                                    _M_id;
+        long volatile                                   _M_CompleteDelegateAssigned;
+        long volatile                                   _M_CallbackMade;
+    };
 
-        static const bool _TakesProgress = true;
-        static const bool _TakesToken = _TakesToken;
+    // ***************************************************************************
+    // Progress Layer (optional):
+    //
 
-        template<typename _Function, typename _ClassPtr>
-        static task<HRESULT> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-        {
-            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet);
-        }
+    template< typename _Attributes, bool _HasProgress, _AsyncResultType _ResultType = SingleResult >
+    class _AsyncProgressBase abstract : public _AsyncInfoBase<_Attributes, _ResultType>
+    {
     };
 
-    template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken>
-    struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, false>
+    template< typename _Attributes, _AsyncResultType _ResultType>
+    class _AsyncProgressBase<_Attributes, true, _ResultType> abstract : public _AsyncInfoBase<_Attributes, _ResultType>
     {
-        typedef typename ABI::Windows::Foundation::IAsyncOperation<_ReturnType> _AsyncBaseType;
-        typedef _Zip _ProgressDelegateType;
-        typedef typename ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_ReturnType> _CompletionDelegateType;
-        typedef typename _ReturnType _ReturnType;
-        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
-        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
-        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator;
-
-        static const bool _TakesProgress = false;
-        static const bool _TakesToken = _TakesToken;
+    public:
 
-        template<typename _Function, typename _ClassPtr>
-        static task<HRESULT> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
+        _AsyncProgressBase() : _AsyncInfoBase<_Attributes, _ResultType>(),
+            _M_progressDelegate(nullptr)
         {
-            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet);
         }
-    };
-
-    template<typename _Function, typename _ProgressType, typename _TaskTraits, bool _TakesToken>
-    struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, true>
-    {
-        typedef typename ABI::Windows::Foundation::IAsyncActionWithProgress<_ProgressType> _AsyncBaseType;
-        typedef typename ABI::Windows::Foundation::IAsyncActionProgressHandler<_ProgressType> _ProgressDelegateType;
-        typedef typename ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_ProgressType> _CompletionDelegateType;
-        typedef void _ReturnType;
-        typedef typename _ProgressType _ProgressType;
-        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
-        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
-        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator;
-
-        static const bool _TakesProgress = true;
-        static const bool _TakesToken = _TakesToken;
 
-        template<typename _Function, typename _ClassPtr>
-        static task<HRESULT> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+        virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler) override
         {
-            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts);
+            HRESULT hr = _CheckValidStateForDelegateCall();
+            if (FAILED(hr)) return hr;
+            *_ProgressHandler = _M_progressDelegate;
+            return S_OK;
         }
-    };
 
-    template<typename _Function, typename _ProgressType, typename _TaskTraits, bool _TakesToken>
-    struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, false>
-    {
-        typedef typename ABI::Windows::Foundation::IAsyncAction _AsyncBaseType;
-        typedef _Zip _ProgressDelegateType;
-        typedef typename ABI::Windows::Foundation::IAsyncActionCompletedHandler _CompletionDelegateType;
-        typedef void _ReturnType;
-        typedef typename _TaskTraits::_AsyncKind _AsyncKind;
-        typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
-        typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator;
+        virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler) override
+        {
+            HRESULT hr = _CheckValidStateForDelegateCall();
+            if (FAILED(hr)) return hr;
+            _M_progressDelegate = _ProgressHandler;
+            _M_progressDelegateContext = _ContextCallback::_CaptureCurrent();
+            return S_OK;
+        }
 
-        static const bool _TakesProgress = false;
-        static const bool _TakesToken = _TakesToken;
+    public:
 
-        template<typename _Function, typename _ClassPtr>
-        static task<HRESULT> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
+        void _FireProgress(const typename _Attributes::_ProgressType_abi& _ProgressValue)
         {
-            return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts);
+            if (_M_progressDelegate != nullptr)
+            {
+                _M_progressDelegateContext._CallInContext([=]() -> HRESULT {
+                    _M_progressDelegate->Invoke((_Attributes::_AsyncBaseType*)this, _ProgressValue);
+                    return S_OK;
+                });
+            }
         }
-    };
 
-    template<typename _Function>
-    struct _AsyncLambdaTypeTraits
-    {
-        typedef typename _CAFunctorOptions<_Function>::_ReturnType _ReturnType;
-        typedef typename _FunctorTypeTraits<_Function>::_Argument1Type _Argument1Type;
-        typedef typename _CAFunctorOptions<_Function>::_ProgressType _ProgressType;
+    private:
 
-        static const bool _TakesProgress = _CAFunctorOptions<_Function>::_TakesProgress;
-        static const bool _TakesToken = _CAFunctorOptions<_Function>::_TakesToken;
+        _ContextCallback _M_progressDelegateContext;
+        typename _Attributes::_ProgressDelegateType* _M_progressDelegate;
+    };
 
-        typedef typename _TaskTypeTraits<_ReturnType> _TaskTraits;
-        typedef typename _AsyncAttributes<_Function, _ProgressType, typename _TaskTraits::_TaskRetType, _TaskTraits, _TakesToken, _TakesProgress> _AsyncAttributes;
+    template<typename _Attributes, _AsyncResultType _ResultType = SingleResult>
+    class _AsyncBaseProgressLayer abstract : public _AsyncProgressBase<_Attributes, _Attributes::_TakesProgress, _ResultType>
+    {
     };
+
     // ***************************************************************************
-    // AsyncInfo (and completion) Layer:
+    // Task Adaptation Layer:
     //
 
     //
-    // Internal base class implementation for async operations (based on internal Windows representation for ABI level async operations)
+    // _AsyncTaskThunkBase provides a bridge between IAsync<Action/Operation> and task.
     //
-    template < typename _Attributes, _AsyncResultType resultType = SingleResult >
-    class _AsyncInfoBase abstract : public Microsoft::WRL::RuntimeClass<
-        Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>, Microsoft::WRL::Implements<typename _Attributes::_AsyncBaseType, ABI::Windows::Foundation::IAsyncInfo>>
+    template<typename _Attributes, typename _ReturnType>
+    class _AsyncTaskThunkBase abstract : public _AsyncBaseProgressLayer<_Attributes>
     {
     public:
-        _AsyncInfoBase() :
-            _M_currentStatus(_AsyncStatusInternal::_AsyncCreated),
-            _M_errorCode(S_OK),
-            _M_completeDelegate(nullptr),
-            _M_CompleteDelegateAssigned(0),
-            _M_CallbackMade(0)
+
+        //AsyncAction*
+        virtual STDMETHODIMP GetResults()
         {
-#if _MSC_VER < 1800
-            _M_id = Concurrency::details::_GetNextAsyncId();
-#else
-            _M_id = Concurrency::details::platform::GetNextAsyncId();
-#endif
+            HRESULT hr = _CheckValidStateForResultsCall();
+            if (FAILED(hr)) return hr;
+            _M_task.get();
+            return S_OK;
         }
+    public:
+        typedef task<_ReturnType> _TaskType;
 
-        virtual STDMETHODIMP GetResults(typename _Attributes::_ReturnType* results)
+        _AsyncTaskThunkBase(const _TaskType& _Task)
+            : _M_task(_Task)
         {
-            (void)results;
-            return E_UNEXPECTED;
         }
 
-    public:
-        STDMETHODIMP get_Id(unsigned int* id)
+        _AsyncTaskThunkBase()
         {
-            HRESULT hr = _CheckValidStateForAsyncInfoCall();
-            if (FAILED(hr)) return hr;
-            if (!id) return E_POINTER;
-            *id = _M_id;
-            return S_OK;
         }
-
-        STDMETHODIMP put_Id(unsigned int id)
+#if _MSC_VER < 1800
+        void _SetTaskCreationAddressHint(void* _SourceAddressHint)
         {
-            HRESULT hr = _CheckValidStateForAsyncInfoCall();
-            if (FAILED(hr)) return hr;
-
-            if (id == 0)
-            {
-                return E_INVALIDARG;
-            }
-            else if (_M_currentStatus != _AsyncStatusInternal::_AsyncCreated)
+            if (!(std::is_same<_Attributes::_AsyncKind, _TypeSelectorAsyncTask>::value))
             {
-                return E_ILLEGAL_METHOD_CALL;
+                // Overwrite the creation address with the return address of create_async unless the
+                // lambda returned a task. If the create async lambda returns a task, that task is reused and
+                // we want to preserve its creation address hint.
+                _M_task._SetTaskCreationAddressHint(_SourceAddressHint);
             }
-
-            _M_id = id;
-            return S_OK;
         }
-        STDMETHODIMP get_Status(ABI::Windows::Foundation::AsyncStatus* status)
+#endif
+    protected:
+        virtual void _OnStart() override
         {
-            HRESULT hr = _CheckValidStateForAsyncInfoCall();
-            if (FAILED(hr)) return hr;
-            if (!status) return E_POINTER;
-
-            _AsyncStatusInternal _Current = _M_currentStatus;
-            //
-            // Map our internal cancel pending to cancelled. This way "pending cancelled" looks to the outside as "cancelled" but
-            // can still transition to "completed" if the operation completes without acknowledging the cancellation request
-            //
-            switch (_Current)
-            {
-            case _AsyncCancelPending:
-                _Current = _AsyncCanceled;
-                break;
-            case _AsyncCreated:
-                _Current = _AsyncStarted;
-                break;
-            default:
-                break;
-            }
-
-            *status = static_cast<ABI::Windows::Foundation::AsyncStatus>(_Current);
-            return S_OK;
+            _M_task.then([=](_TaskType _Antecedent) -> HRESULT {
+                try
+                {
+                    _Antecedent.get();
+                }
+                catch (Concurrency::task_canceled&)
+                {
+                    _TryTransitionToCancelled();
+                }
+                catch (IRestrictedErrorInfo*& _Ex)
+                {
+                    HRESULT hr;
+                    HRESULT _hr;
+                    hr = _Ex->GetErrorDetails(NULL, &_hr, NULL, NULL);
+                    if (SUCCEEDED(hr)) hr = _hr;
+                    _TryTransitionToError(hr);
+                }
+                catch (...)
+                {
+                    _TryTransitionToError(E_FAIL);
+                }
+                return _FireCompletion();
+            });
         }
 
-        STDMETHODIMP get_ErrorCode(HRESULT* errorCode)
+    protected:
+        _TaskType _M_task;
+        Concurrency::cancellation_token_source _M_cts;
+    };
+
+    template<typename _Attributes, typename _ReturnType, typename _Return>
+    class _AsyncTaskReturn abstract : public _AsyncTaskThunkBase<_Attributes, _Return>
+    {
+    public:
+        //AsyncOperation*
+        virtual STDMETHODIMP GetResults(_ReturnType* results)
         {
-            HRESULT hr = _CheckValidStateForAsyncInfoCall();
+            HRESULT hr = _CheckValidStateForResultsCall();
             if (FAILED(hr)) return hr;
-            if (!hr) return hr;
-            *errorCode = _M_errorCode;
+            _M_task.get();
+            *results = _M_results;
             return S_OK;
         }
-
-        STDMETHODIMP get_Progress(typename _Attributes::_ProgressDelegateType** _ProgressHandler)
+        template <typename _Function>
+#if _MSC_VER >= 1800
+        void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack)
         {
-            return _GetOnProgress(_ProgressHandler);
+            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results, _callstack);
         }
-
-        STDMETHODIMP put_Progress(typename _Attributes::_ProgressDelegateType* _ProgressHandler)
+#else
+        void DoCreateTask(_Function _func)
         {
-            return _PutOnProgress(_ProgressHandler);
+            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results);
         }
+#endif
+    protected:
+        _ReturnType _M_results;
+    };
 
-        STDMETHODIMP Cancel()
+    template<typename _Attributes, typename _ReturnType>
+    class _AsyncTaskReturn<_Attributes, _ReturnType, void> abstract : public _AsyncTaskThunkBase<_Attributes, void>
+    {
+    public:
+        template <typename _Function>
+#if _MSC_VER >= 1800
+        void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack)
         {
-            if (_TransitionToState(_AsyncCancelPending))
-            {
-                _OnCancel();
-            }
-            return S_OK;
+            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, _callstack);
         }
-
-        STDMETHODIMP Close()
+#else
+        void DoCreateTask(_Function _func)
         {
-            if (_TransitionToState(_AsyncClosed))
-            {
-                _OnClose();
-            }
-            else
-            {
-                if (_M_currentStatus != _AsyncClosed) // Closed => Closed transition is just ignored
-                {
-                    return E_ILLEGAL_STATE_CHANGE;
-                }
-            }
-            return S_OK;
+            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts);
+        }
+#endif
+    };
+
+    template<typename _Attributes>
+    class _AsyncTaskReturn<_Attributes, void, task<void>> abstract : public _AsyncTaskThunkBase<_Attributes, task<void>>
+    {
+    public:
+        template <typename _Function>
+#if _MSC_VER >= 1800
+        void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack)
+        {
+            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results, _callstack);
         }
-
-        virtual STDMETHODIMP get_Completed(typename _Attributes::_CompletionDelegateType** _CompleteHandler)
+#else
+        void DoCreateTask(_Function _func)
         {
-            _CheckValidStateForDelegateCall();
-            if (!_CompleteHandler) return E_POINTER;
-            *_CompleteHandler = _M_completeDelegate;
-            return S_OK;
+            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results);
         }
+#endif
+    protected:
+        task<void> _M_results;
+    };
 
-        virtual STDMETHODIMP put_Completed(typename _Attributes::_CompletionDelegateType* _CompleteHandler)
+    template<typename _Attributes>
+    class _AsyncTaskThunk : public _AsyncTaskReturn<_Attributes, typename _Attributes::_ReturnType_abi, typename _Attributes::_ReturnType>
+    {
+    public:
+
+        _AsyncTaskThunk(const _TaskType& _Task) :
+            _AsyncTaskThunkBase(_Task)
         {
-            _CheckValidStateForDelegateCall();
-            // this delegate property is "write once"
-            if (InterlockedIncrement(&_M_CompleteDelegateAssigned) == 1)
-            {
-                _M_completeDelegateContext = _ContextCallback::_CaptureCurrent();
-                _M_completeDelegate = _CompleteHandler;
-                // Guarantee that the write of _M_completeDelegate is ordered with respect to the read of state below
-                // as perceived from _FireCompletion on another thread.
-                MemoryBarrier();
-                if (_IsTerminalState())
-                {
-                    _FireCompletion();
-                }
-            }
-            else
-            {
-                return E_ILLEGAL_DELEGATE_ASSIGNMENT;
-            }
-            return S_OK;
         }
 
-    protected:
-        // _Start - this is not externally visible since async operations "hot start" before returning to the caller
-        STDMETHODIMP _Start()
+        _AsyncTaskThunk()
         {
-            if (_TransitionToState(_AsyncStarted))
-            {
-                _OnStart();
-            }
-            else
-            {
-                return E_ILLEGAL_STATE_CHANGE;
-            }
-            return S_OK;
         }
 
-        void _FireCompletion()
-        {
-            _TryTransitionToCompleted();
+    protected:
 
-            // we guarantee that completion can only ever be fired once
-            if (_M_completeDelegate != nullptr && InterlockedIncrement(&_M_CallbackMade) == 1)
-            {
-                _M_completeDelegateContext._CallInContext([=]() -> HRESULT {
-                    ABI::Windows::Foundation::AsyncStatus status;
-                    if (SUCCEEDED(this->get_Status(&status)))
-                        _M_completeDelegate->Invoke((_Attributes::_AsyncBaseType*)this, status);
-                    _M_completeDelegate = nullptr;
-                    return S_OK;
-                });
-            }
+        virtual void _OnClose() override
+        {
         }
 
-        virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler)
+        virtual void _OnCancel() override
         {
-            (void)_ProgressHandler;
-            return E_UNEXPECTED;
+            _M_cts.cancel();
         }
+    };
 
-        virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler)
+    // ***************************************************************************
+    // Async Creation Layer:
+    //
+    template<typename _Function>
+    class _AsyncTaskGeneratorThunk : public _AsyncTaskThunk<typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes>
+    {
+    public:
+
+        typedef typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes _Attributes;
+        typedef typename _AsyncTaskThunk<_Attributes> _Base;
+        typedef typename _Attributes::_AsyncBaseType _AsyncBaseType;
+
+#if _MSC_VER >= 1800
+        _AsyncTaskGeneratorThunk(const _Function& _Func, const _TaskCreationCallstack &_callstack) : _M_func(_Func), _M_creationCallstack(_callstack)
+#else
+        _AsyncTaskGeneratorThunk(const _Function& _Func) : _M_func(_Func)
+#endif
         {
-            (void)_ProgressHandler;
-            return E_UNEXPECTED;
+            // Virtual call here is safe as the class is declared 'sealed'
+            _Start();
         }
 
+    protected:
 
-        bool _TryTransitionToCompleted()
+        //
+        // The only thing we must do different from the base class is we must spin the hot task on transition from Created->Started. Otherwise,
+        // let the base thunk handle everything.
+        //
+
+        virtual void _OnStart() override
         {
-            return _TransitionToState(_AsyncStatusInternal::_AsyncCompleted);
+            //
+            // Call the appropriate task generator to actually produce a task of the expected type. This might adapt the user lambda for progress reports,
+            // wrap the return result in a task, or allow for direct return of a task depending on the form of the lambda.
+            //
+#if _MSC_VER >= 1800
+            DoCreateTask<_Function>(_M_func, _M_creationCallstack);
+#else
+            DoCreateTask<_Function>(_M_func);
+#endif
+            _Base::_OnStart();
         }
 
-        bool _TryTransitionToCancelled()
+        virtual void _OnCancel() override
         {
-            return _TransitionToState(_AsyncStatusInternal::_AsyncCanceled);
+            _Base::_OnCancel();
         }
 
-        bool _TryTransitionToError(const HRESULT error)
+    private:
+#if _MSC_VER >= 1800
+        _TaskCreationCallstack _M_creationCallstack;
+#endif
+        _Function _M_func;
+    };
+} // namespace details
+
+/// <summary>
+///     Creates a Windows Runtime asynchronous construct based on a user supplied lambda or function object. The return type of <c>create_async</c> is
+///     one of either <c>IAsyncAction^</c>, <c>IAsyncActionWithProgress&lt;TProgress&gt;^</c>, <c>IAsyncOperation&lt;TResult&gt;^</c>, or
+///     <c>IAsyncOperationWithProgress&lt;TResult, TProgress&gt;^</c> based on the signature of the lambda passed to the method.
+/// </summary>
+/// <param name="_Func">
+///     The lambda or function object from which to create a Windows Runtime asynchronous construct.
+/// </param>
+/// <returns>
+///     An asynchronous construct represented by an IAsyncAction^, IAsyncActionWithProgress&lt;TProgress&gt;^, IAsyncOperation&lt;TResult&gt;^, or an
+///     IAsyncOperationWithProgress&lt;TResult, TProgress&gt;^. The interface returned depends on the signature of the lambda passed into the function.
+/// </returns>
+/// <remarks>
+///     The return type of the lambda determines whether the construct is an action or an operation.
+///     <para>Lambdas that return void cause the creation of actions. Lambdas that return a result of type <c>TResult</c> cause the creation of
+///     operations of TResult.</para>
+///     <para>The lambda may also return a <c>task&lt;TResult&gt;</c> which encapsulates the aysnchronous work within itself or is the continuation of
+///     a chain of tasks that represent the asynchronous work. In this case, the lambda itself is executed inline, since the tasks are the ones that
+///     execute asynchronously, and the return type of the lambda is unwrapped to produce the asynchronous construct returned by <c>create_async</c>.
+///     This implies that a lambda that returns a task&lt;void&gt; will cause the creation of actions, and a lambda that returns a task&lt;TResult&gt; will
+///     cause the creation of operations of TResult.</para>
+///     <para>The lambda may take either zero, one or two arguments. The valid arguments are <c>progress_reporter&lt;TProgress&gt;</c> and
+///     <c>cancellation_token</c>, in that order if both are used. A lambda without arguments causes the creation of an asynchronous construct without
+///     the capability for progress reporting. A lambda that takes a progress_reporter&lt;TProgress&gt; will cause <c>create_async</c> to return an asynchronous
+///     construct which reports progress of type TProgress each time the <c>report</c> method of the progress_reporter object is called. A lambda that
+///     takes a cancellation_token may use that token to check for cancellation, or pass it to tasks that it creates so that cancellation of the
+///     asynchronous construct causes cancellation of those tasks.</para>
+///     <para>If the body of the lambda or function object returns a result (and not a task&lt;TResult&gt;), the lamdba will be executed
+///     asynchronously within the process MTA in the context of a task the Runtime implicitly creates for it. The <c>IAsyncInfo::Cancel</c> method will
+///     cause cancellation of the implicit task.</para>
+///     <para>If the body of the lambda returns a task, the lamba executes inline, and by declaring the lambda to take an argument of type
+///     <c>cancellation_token</c> you can trigger cancellation of any tasks you create within the lambda by passing that token in when you create them.
+///     You may also use the <c>register_callback</c> method on the token to cause the Runtime to invoke a callback when you call <c>IAsyncInfo::Cancel</c> on
+///     the async operation or action produced..</para>
+///     <para>This function is only available to Windows Store apps.</para>
+/// </remarks>
+/// <seealso cref="task Class"/>
+/// <seealso cref="progress_reporter Class"/>
+/// <seealso cref="cancelation_token Class"/>
+/**/
+template<typename _ReturnType, typename _Function>
+__declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
+details::_AsyncTaskGeneratorThunk<_Function>* create_async(const _Function& _Func)
+{
+    static_assert(std::is_same<decltype(details::_IsValidCreateAsync<_ReturnType>(_Func, 0, 0, 0, 0, 0, 0, 0, 0)), std::true_type>::value,
+        "argument to create_async must be a callable object taking zero, one, two or three arguments");
+#if _MSC_VER >= 1800
+    Microsoft::WRL::ComPtr<details::_AsyncTaskGeneratorThunk<_Function>> _AsyncInfo = Microsoft::WRL::Make<details::_AsyncTaskGeneratorThunk<_Function>>(_Func, _CAPTURE_CALLSTACK());
+#else
+    Microsoft::WRL::ComPtr<details::_AsyncTaskGeneratorThunk<_Function>> _AsyncInfo = Microsoft::WRL::Make<details::_AsyncTaskGeneratorThunk<_Function>>(_Func);
+    _AsyncInfo->_SetTaskCreationAddressHint(_ReturnAddress());
+#endif
+    return _AsyncInfo.Detach();
+}
+
+namespace details
+{
+#if _MSC_VER < 1800
+    // Internal API which retrieves the next async id.
+    _CRTIMP2 unsigned int __cdecl _GetNextAsyncId();
+#endif
+    // Helper struct for when_all operators to know when tasks have completed
+    template<typename _Type>
+    struct _RunAllParam
+    {
+        _RunAllParam() : _M_completeCount(0), _M_numTasks(0)
         {
-            _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_errorCode), error, S_OK);
-            return _TransitionToState(_AsyncStatusInternal::_AsyncError);
         }
 
-        // This method checks to see if the delegate properties can be
-        // modified in the current state and generates the appropriate
-        // error hr in the case of violation.
-        inline HRESULT _CheckValidStateForDelegateCall()
+        void _Resize(size_t _Len, bool _SkipVector = false)
         {
-            if (_M_currentStatus == _AsyncClosed)
+            _M_numTasks = _Len;
+            if (!_SkipVector)
+#if _MSC_VER >= 1800
             {
-                return E_ILLEGAL_METHOD_CALL;
+                _M_vector._Result.resize(_Len);
             }
-            return S_OK;
+#else
+                _M_vector.resize(_Len);
+            _M_contexts.resize(_Len);
+#endif
         }
 
-        // This method checks to see if results can be collected in the
-        // current state and generates the appropriate error hr in
-        // the case of a violation.
-        inline HRESULT _CheckValidStateForResultsCall()
+        task_completion_event<_Unit_type>       _M_completed;
+        atomic_size_t                           _M_completeCount;
+#if _MSC_VER >= 1800
+        _ResultHolder<std::vector<_Type> >      _M_vector;
+        _ResultHolder<_Type>                    _M_mergeVal;
+#else
+        std::vector<_Type>                      _M_vector;
+        std::vector<_ContextCallback>           _M_contexts;
+        _Type                                   _M_mergeVal;
+#endif
+        size_t                                  _M_numTasks;
+    };
+
+#if _MSC_VER >= 1800
+    template<typename _Type>
+    struct _RunAllParam<std::vector<_Type> >
+    {
+        _RunAllParam() : _M_completeCount(0), _M_numTasks(0)
         {
-            _AsyncStatusInternal _Current = _M_currentStatus;
+        }
 
-            if (_Current == _AsyncError)
-            {
-                return _M_errorCode;
-            }
-#pragma warning(push)
-#pragma warning(disable: 4127) // Conditional expression is constant
-            // single result illegal before transition to Completed or Cancelled state
-            if (resultType == SingleResult)
-#pragma warning(pop)
-            {
-                if (_Current != _AsyncCompleted)
-                {
-                    return E_ILLEGAL_METHOD_CALL;
-                }
-            }
-            // multiple results can be called after Start has been called and before/after Completed
-            else if (_Current != _AsyncStarted &&
-                _Current != _AsyncCancelPending &&
-                _Current != _AsyncCanceled &&
-                _Current != _AsyncCompleted)
+        void _Resize(size_t _Len, bool _SkipVector = false)
+        {
+            _M_numTasks = _Len;
+
+            if (!_SkipVector)
             {
-                return E_ILLEGAL_METHOD_CALL;
+                _M_vector.resize(_Len);
             }
-            return S_OK;
         }
 
-        // This method can be called by derived classes periodically to determine
-        // whether the asynchronous operation should continue processing or should
-        // be halted.
-        inline bool _ContinueAsyncOperation()
+        task_completion_event<_Unit_type>       _M_completed;
+        std::vector<_ResultHolder<std::vector<_Type> > >  _M_vector;
+        atomic_size_t     _M_completeCount;
+        size_t                                  _M_numTasks;
+    };
+#endif
+
+    // Helper struct specialization for void
+    template<>
+#if _MSC_VER >= 1800
+    struct _RunAllParam<_Unit_type>
+#else
+    struct _RunAllParam<void>
+#endif
+    {
+        _RunAllParam() : _M_completeCount(0), _M_numTasks(0)
         {
-            return _M_currentStatus == _AsyncStarted;
         }
 
-        // These two methods are used to allow the async worker implementation do work on
-        // state transitions. No real "work" should be done in these methods. In other words
-        // they should not block for a long time on UI timescales.
-        virtual void _OnStart() = 0;
-        virtual void _OnClose() = 0;
-        virtual void _OnCancel() = 0;
+        void _Resize(size_t _Len)
+        {
+            _M_numTasks = _Len;
+        }
 
-    private:
+        task_completion_event<_Unit_type> _M_completed;
+        atomic_size_t _M_completeCount;
+        size_t _M_numTasks;
+    };
 
-        // This method is used to check if calls to the AsyncInfo properties
-        // (id, status, errorcode) are legal in the current state. It also
-        // generates the appropriate error hr to return in the case of an
-        // illegal call.
-        inline HRESULT _CheckValidStateForAsyncInfoCall()
+    inline void _JoinAllTokens_Add(const Concurrency::cancellation_token_source& _MergedSrc, Concurrency::details::_CancellationTokenState *_PJoinedTokenState)
+    {
+        if (_PJoinedTokenState != nullptr && _PJoinedTokenState != Concurrency::details::_CancellationTokenState::_None())
+        {
+            Concurrency::cancellation_token _T = Concurrency::cancellation_token::_FromImpl(_PJoinedTokenState);
+            _T.register_callback([=](){
+                _MergedSrc.cancel();
+            });
+        }
+    }
+
+    template<typename _ElementType, typename _Function, typename _TaskType>
+    void _WhenAllContinuationWrapper(_RunAllParam<_ElementType>* _PParam, _Function _Func, task<_TaskType>& _Task)
+    {
+        if (_Task._GetImpl()->_IsCompleted())
         {
-            _AsyncStatusInternal _Current = _M_currentStatus;
-            if (_Current == _AsyncClosed)
+            _Func();
+#if _MSC_VER >= 1800
+            if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#else
+            if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#endif
             {
-                return E_ILLEGAL_METHOD_CALL;
+                // Inline execute its direct continuation, the _ReturnTask
+                _PParam->_M_completed.set(_Unit_type());
+                // It's safe to delete it since all usage of _PParam in _ReturnTask has been finished.
+                delete _PParam;
             }
-            else if (_Current == _AsyncCreated)
+        }
+        else
+        {
+            _CONCRT_ASSERT(_Task._GetImpl()->_IsCanceled());
+            if (_Task._GetImpl()->_HasUserException())
             {
-                return E_ASYNC_OPERATION_NOT_STARTED;
+                // _Cancel will return false if the TCE is already canceled with or without exception
+                _PParam->_M_completed._Cancel(_Task._GetImpl()->_GetExceptionHolder());
+            }
+            else
+            {
+                _PParam->_M_completed._Cancel();
+            }
+#if _MSC_VER >= 1800
+            if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#else
+            if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#endif
+            {
+                delete _PParam;
             }
-            return S_OK;
         }
+    }
 
-        inline bool _TransitionToState(const _AsyncStatusInternal _NewState)
+    template<typename _ElementType, typename _Iterator>
+    struct _WhenAllImpl
+    {
+#if _MSC_VER >= 1800
+        static task<std::vector<_ElementType>> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
+#else
+        static task<std::vector<_ElementType>> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
+#endif
         {
-            _AsyncStatusInternal _Current = _M_currentStatus;
+#if _MSC_VER >= 1800
+            Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
+#endif
+            auto _PParam = new _RunAllParam<_ElementType>();
+            Concurrency::cancellation_token_source _MergedSource;
+
+            // Step1: Create task completion event.
+#if _MSC_VER >= 1800
+            task_options _Options(_TaskOptions);
+            _Options.set_cancellation_token(_MergedSource.get_token());
+            task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options);
+#else
+            task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
+#endif
+            // The return task must be created before step 3 to enforce inline execution.
+            auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ElementType>* retVal) -> HRESULT {
+#if _MSC_VER >= 1800
+                * retVal = _PParam->_M_vector.Get();
+#else
+                auto _Result = _PParam->_M_vector; // copy by value
 
-            // This enforces the valid state transitions of the asynchronous worker object
-            // state machine.
-            switch (_NewState)
-            {
-            case _AsyncStatusInternal::_AsyncStarted:
-                if (_Current != _AsyncCreated)
+                size_t _Index = 0;
+                for (auto _It = _Result.begin(); _It != _Result.end(); ++_It)
                 {
-                    return false;
+                    *_It = _ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_Index++], false);
                 }
-                break;
-            case _AsyncStatusInternal::_AsyncCompleted:
-                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
+                *retVal = _Result;
+#endif
+                return S_OK;
+#if _MSC_VER >= 1800
+            }, nullptr);
+#else
+            }, nullptr, true);
+#endif
+            // Step2: Combine and check tokens, and count elements in range.
+            if (_PTokenState)
+            {
+                details::_JoinAllTokens_Add(_MergedSource, _PTokenState);
+                _PParam->_Resize(static_cast<size_t>(std::distance(_Begin, _End)));
+            }
+            else
+            {
+                size_t _TaskNum = 0;
+                for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
                 {
-                    return false;
+                    _TaskNum++;
+                    details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState);
                 }
-                break;
-            case _AsyncStatusInternal::_AsyncCancelPending:
-                if (_Current != _AsyncStarted)
+                _PParam->_Resize(_TaskNum);
+            }
+
+            // Step3: Check states of previous tasks.
+            if (_Begin == _End)
+            {
+                _PParam->_M_completed.set(_Unit_type());
+                delete _PParam;
+            }
+            else
+            {
+                size_t _Index = 0;
+                for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
                 {
-                    return false;
+                    if (_PTask->is_apartment_aware())
+                    {
+                        _ReturnTask._SetAsync();
+                    }
+
+                    _PTask->_Then([_PParam, _Index](task<_ElementType> _ResultTask) -> HRESULT {
+
+#if _MSC_VER >= 1800
+                        //  Dev10 compiler bug
+                        typedef _ElementType _ElementTypeDev10;
+                        auto _PParamCopy = _PParam;
+                        auto _IndexCopy = _Index;
+                        auto _Func = [_PParamCopy, _IndexCopy, &_ResultTask](){
+                            _PParamCopy->_M_vector._Result[_IndexCopy] = _ResultTask._GetImpl()->_GetResult();
+                        };
+#else
+                        auto _Func = [_PParam, _Index, &_ResultTask](){
+                            _PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult();
+                            _PParam->_M_contexts[_Index] = _ResultContext<_ElementType>::_GetContext(false);
+                        };
+#endif
+                        _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
+                        return S_OK;
+#if _MSC_VER >= 1800
+                    }, Concurrency::details::_CancellationTokenState::_None());
+#else
+                    }, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+
+                    _Index++;
                 }
-                break;
-            case _AsyncStatusInternal::_AsyncCanceled:
-                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
+            }
+
+            return _ReturnTask;
+        }
+    };
+
+    template<typename _ElementType, typename _Iterator>
+    struct _WhenAllImpl<std::vector<_ElementType>, _Iterator>
+    {
+#if _MSC_VER >= 1800
+        static task<std::vector<_ElementType>> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
+#else
+        static task<std::vector<_ElementType>> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
+#endif
+        {
+#if _MSC_VER >= 1800
+            Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
+#endif
+            auto _PParam = new _RunAllParam<std::vector<_ElementType>>();
+            Concurrency::cancellation_token_source _MergedSource;
+
+            // Step1: Create task completion event.
+#if _MSC_VER >= 1800
+            task_options _Options(_TaskOptions);
+            _Options.set_cancellation_token(_MergedSource.get_token());
+            task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options);
+#else
+            task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
+#endif
+            // The return task must be created before step 3 to enforce inline execution.
+            auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ElementType>* retVal) -> HRESULT {
+                _CONCRT_ASSERT(_PParam->_M_completeCount == _PParam->_M_numTasks);
+                std::vector<_ElementType> _Result;
+                for (size_t _I = 0; _I < _PParam->_M_numTasks; _I++)
                 {
-                    return false;
+#if _MSC_VER >= 1800
+                    const std::vector<_ElementType>& _Vec = _PParam->_M_vector[_I].Get();
+#else
+                    std::vector<_ElementType>& _Vec = _PParam->_M_vector[_I];
+
+                    for (auto _It = _Vec.begin(); _It != _Vec.end(); ++_It)
+                    {
+                        *_It = _ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_I], false);
+                    }
+#endif
+                    _Result.insert(_Result.end(), _Vec.begin(), _Vec.end());
                 }
-                break;
-            case _AsyncStatusInternal::_AsyncError:
-                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
+                *retVal = _Result;
+                return S_OK;
+#if _MSC_VER >= 1800
+            }, nullptr);
+#else
+            }, nullptr, true);
+#endif
+
+            // Step2: Combine and check tokens, and count elements in range.
+            if (_PTokenState)
+            {
+                details::_JoinAllTokens_Add(_MergedSource, _PTokenState);
+                _PParam->_Resize(static_cast<size_t>(std::distance(_Begin, _End)));
+            }
+            else
+            {
+                size_t _TaskNum = 0;
+                for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
                 {
-                    return false;
+                    _TaskNum++;
+                    details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState);
                 }
-                break;
-            case _AsyncStatusInternal::_AsyncClosed:
-                if (!_IsTerminalState(_Current))
+                _PParam->_Resize(_TaskNum);
+            }
+
+            // Step3: Check states of previous tasks.
+            if (_Begin == _End)
+            {
+                _PParam->_M_completed.set(_Unit_type());
+                delete _PParam;
+            }
+            else
+            {
+                size_t _Index = 0;
+                for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
                 {
-                    return false;
+                    if (_PTask->is_apartment_aware())
+                    {
+                        _ReturnTask._SetAsync();
+                    }
+
+                    _PTask->_Then([_PParam, _Index](task<std::vector<_ElementType>> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+                        //  Dev10 compiler bug
+                        typedef _ElementType _ElementTypeDev10;
+                        auto _PParamCopy = _PParam;
+                        auto _IndexCopy = _Index;
+                        auto _Func = [_PParamCopy, _IndexCopy, &_ResultTask]() {
+                            _PParamCopy->_M_vector[_IndexCopy].Set(_ResultTask._GetImpl()->_GetResult());
+                        };
+#else
+                        auto _Func = [_PParam, _Index, &_ResultTask]() {
+                            _PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult();
+                            _PParam->_M_contexts[_Index] = _ResultContext<_ElementType>::_GetContext(false);
+                        };
+#endif
+                        _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
+                        return S_OK;
+#if _MSC_VER >= 1800
+                    }, Concurrency::details::_CancellationTokenState::_None());
+#else
+                    }, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+
+                    _Index++;
                 }
-                break;
-            default:
-                return false;
-                break;
             }
 
-            // attempt the transition to the new state
-            // Note: if currentStatus_ == _Current, then there was no intervening write
-            // by the async work object and the swap succeeded.
-            _AsyncStatusInternal _RetState = static_cast<_AsyncStatusInternal>(
-                _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_currentStatus),
-                _NewState,
-                static_cast<LONG>(_Current)));
-
-            // ICE returns the former state, if the returned state and the
-            // state we captured at the beginning of this method are the same,
-            // the swap succeeded.
-            return (_RetState == _Current);
+            return  _ReturnTask;
         }
+    };
 
-        inline bool _IsTerminalState()
+    template<typename _Iterator>
+    struct _WhenAllImpl<void, _Iterator>
+    {
+#if _MSC_VER >= 1800
+        static task<void> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
+#else
+        static task<void> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
+#endif
         {
-            return _IsTerminalState(_M_currentStatus);
-        }
+#if _MSC_VER >= 1800
+            Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
+#endif
+            auto _PParam = new _RunAllParam<_Unit_type>();
+            Concurrency::cancellation_token_source _MergedSource;
+
+            // Step1: Create task completion event.
+#if _MSC_VER >= 1800
+            task_options _Options(_TaskOptions);
+            _Options.set_cancellation_token(_MergedSource.get_token());
+            task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options);
+#else
+            task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
+#endif
+            // The return task must be created before step 3 to enforce inline execution.
+            auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type) -> HRESULT { return S_OK;
+#if _MSC_VER >= 1800
+            }, nullptr);
+#else
+            }, nullptr, false);
+#endif
 
-        inline bool _IsTerminalState(_AsyncStatusInternal status)
-        {
-            return (status == _AsyncError ||
-                status == _AsyncCanceled ||
-                status == _AsyncCompleted ||
-                status == _AsyncClosed);
-        }
+            // Step2: Combine and check tokens, and count elements in range.
+            if (_PTokenState)
+            {
+                details::_JoinAllTokens_Add(_MergedSource, _PTokenState);
+                _PParam->_Resize(static_cast<size_t>(std::distance(_Begin, _End)));
+            }
+            else
+            {
+                size_t _TaskNum = 0;
+                for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
+                {
+                    _TaskNum++;
+                    details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState);
+                }
+                _PParam->_Resize(_TaskNum);
+            }
 
-    private:
+            // Step3: Check states of previous tasks.
+            if (_Begin == _End)
+            {
+                _PParam->_M_completed.set(_Unit_type());
+                delete _PParam;
+            }
+            else
+            {
+                for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
+                {
+                    if (_PTask->is_apartment_aware())
+                    {
+                        _ReturnTask._SetAsync();
+                    }
 
-        _ContextCallback        _M_completeDelegateContext;
-        typename _Attributes::_CompletionDelegateType*  volatile _M_completeDelegate;
-        _AsyncStatusInternal volatile                   _M_currentStatus;
-        HRESULT volatile                                _M_errorCode;
-        unsigned int                                    _M_id;
-        long volatile                                   _M_CompleteDelegateAssigned;
-        long volatile                                   _M_CallbackMade;
-    };
+                    _PTask->_Then([_PParam](task<void> _ResultTask) -> HRESULT {
 
-    // ***************************************************************************
-    // Progress Layer (optional):
-    //
+                        auto _Func = []() -> HRESULT { return S_OK;  };
+                        _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
+                        return S_OK;
+#if _MSC_VER >= 1800
+                    }, Concurrency::details::_CancellationTokenState::_None());
+#else
+                    }, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+                }
+            }
 
-    template< typename _Attributes, bool _HasProgress, _AsyncResultType _ResultType = SingleResult >
-    class _AsyncProgressBase abstract : public _AsyncInfoBase<_Attributes, _ResultType>
-    {
+            return _ReturnTask;
+        }
     };
 
-    template< typename _Attributes, _AsyncResultType _ResultType>
-    class _AsyncProgressBase<_Attributes, true, _ResultType> abstract : public _AsyncInfoBase<_Attributes, _ResultType>
-    {
-    public:
+    template<typename _ReturnType>
+    task<std::vector<_ReturnType>> _WhenAllVectorAndValue(const task<std::vector<_ReturnType>>& _VectorTask, const task<_ReturnType>& _ValueTask,
+        bool _OutputVectorFirst)
+    {
+        auto _PParam = new _RunAllParam<_ReturnType>();
+        Concurrency::cancellation_token_source _MergedSource;
+
+        // Step1: Create task completion event.
+        task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
+        // The return task must be created before step 3 to enforce inline execution.
+        auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ReturnType>* retVal) -> HRESULT {
+            _CONCRT_ASSERT(_PParam->_M_completeCount == 2);
+#if _MSC_VER >= 1800
+            auto _Result = _PParam->_M_vector.Get(); // copy by value
+            auto _mergeVal = _PParam->_M_mergeVal.Get();
+#else
+            auto _Result = _PParam->_M_vector; // copy by value
+            for (auto _It = _Result.begin(); _It != _Result.end(); ++_It)
+            {
+                *_It = _ResultContext<_ReturnType>::_GetValue(*_It, _PParam->_M_contexts[0], false);
+            }
+#endif
 
-        _AsyncProgressBase() : _AsyncInfoBase<_Attributes, _ResultType>(),
-            _M_progressDelegate(nullptr)
-        {
-        }
+            if (_OutputVectorFirst == true)
+            {
+#if _MSC_VER >= 1800
+                _Result.push_back(_mergeVal);
+#else
+                _Result.push_back(_ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false));
+#endif
+            }
+            else
+            {
+#if _MSC_VER >= 1800
+                _Result.insert(_Result.begin(), _mergeVal);
+#else
+                _Result.insert(_Result.begin(), _ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false));
+#endif
+            }
+            *retVal = _Result;
+            return S_OK;
+        }, nullptr, true);
 
-        virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler) override
+        // Step2: Combine and check tokens.
+        _JoinAllTokens_Add(_MergedSource, _VectorTask._GetImpl()->_M_pTokenState);
+        _JoinAllTokens_Add(_MergedSource, _ValueTask._GetImpl()->_M_pTokenState);
+
+        // Step3: Check states of previous tasks.
+        _PParam->_Resize(2, true);
+
+        if (_VectorTask.is_apartment_aware() || _ValueTask.is_apartment_aware())
         {
-            HRESULT hr = _CheckValidStateForDelegateCall();
-            if (FAILED(hr)) return hr;
-            *_ProgressHandler = _M_progressDelegate;
-            return S_OK;
+            _ReturnTask._SetAsync();
         }
+        _VectorTask._Then([_PParam](task<std::vector<_ReturnType>> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+            //  Dev10 compiler bug
+            typedef _ReturnType _ReturnTypeDev10;
+            auto _PParamCopy = _PParam;
+            auto _Func = [_PParamCopy, &_ResultTask]() {
+                auto _ResultLocal = _ResultTask._GetImpl()->_GetResult();
+                _PParamCopy->_M_vector.Set(_ResultLocal);
+            };
+#else
+            auto _Func = [_PParam, &_ResultTask]() {
+                _PParam->_M_vector = _ResultTask._GetImpl()->_GetResult();
+                _PParam->_M_contexts[0] = _ResultContext<_ReturnType>::_GetContext(false);
+            };
+#endif
 
-        virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler) override
-        {
-            HRESULT hr = _CheckValidStateForDelegateCall();
-            if (FAILED(hr)) return hr;
-            _M_progressDelegate = _ProgressHandler;
-            _M_progressDelegateContext = _ContextCallback::_CaptureCurrent();
+            _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
             return S_OK;
-        }
+#if _MSC_VER >= 1800
+        }, _CancellationTokenState::_None());
+#else
+        }, _CancellationTokenState::_None(), false);
+#endif
+        _ValueTask._Then([_PParam](task<_ReturnType> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+            //  Dev10 compiler bug
+            typedef _ReturnType _ReturnTypeDev10;
+            auto _PParamCopy = _PParam;
+            auto _Func = [_PParamCopy, &_ResultTask]() {
+                auto _ResultLocal = _ResultTask._GetImpl()->_GetResult();
+                _PParamCopy->_M_mergeVal.Set(_ResultLocal);
+            };
+#else
+            auto _Func = [_PParam, &_ResultTask]() {
+                _PParam->_M_mergeVal = _ResultTask._GetImpl()->_GetResult();
+                _PParam->_M_contexts[1] = _ResultContext<_ReturnType>::_GetContext(false);
+            };
+#endif
+            _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
+            return S_OK;
+#if _MSC_VER >= 1800
+        }, _CancellationTokenState::_None());
+#else
+        }, _CancellationTokenState::_None(), false);
+#endif
 
-    public:
+        return _ReturnTask;
+    }
+} // namespace details
 
-        void _FireProgress(const typename _Attributes::_ProgressType& _ProgressValue)
-        {
-            if (_M_progressDelegate != nullptr)
-            {
-                _M_progressDelegateContext._CallInContext([=] -> HRESULT {
-                    _M_progressDelegate((_Attributes::_AsyncBaseType*)this, _ProgressValue);
-                    return S_OK;
-                });
-            }
-        }
+#if _MSC_VER < 1800
+/// <summary>
+///     Creates a task that will complete successfully when all of the tasks supplied as arguments complete successfully.
+/// </summary>
+/// <typeparam name="_Iterator">
+///     The type of the input iterator.
+/// </typeparam>
+/// <param name="_Begin">
+///     The position of the first element in the range of elements to be combined into the resulting task.
+/// </param>
+/// <param name="_End">
+///     The position of the first element beyond the range of elements to be combined into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes sucessfully when all of the input tasks have completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;&gt;</c>. If the input tasks are of type <c>void</c> the output
+///     task will also be a <c>task&lt;void&gt;</c>.
+/// </returns>
+/// <remarks>
+///     If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception,
+///     if one is encoutered, will be thrown if you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template <typename _Iterator>
+auto when_all(_Iterator _Begin, _Iterator _End)
+-> decltype (details::_WhenAllImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(nullptr, _Begin, _End))
+{
+    typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
+    return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(nullptr, _Begin, _End);
+}
+#endif
 
-    private:
+/// <summary>
+///     Creates a task that will complete successfully when all of the tasks supplied as arguments complete successfully.
+/// </summary>
+/// <typeparam name="_Iterator">
+///     The type of the input iterator.
+/// </typeparam>
+/// <param name="_Begin">
+///     The position of the first element in the range of elements to be combined into the resulting task.
+/// </param>
+/// <param name="_End">
+///     The position of the first element beyond the range of elements to be combined into the resulting task.
+/// </param>
+/// <param name="_CancellationToken">
+///     The cancellation token which controls cancellation of the returned task. If you do not provide a cancellation token, the resulting
+///     task will be created with a token that is a combination of all the cancelable tokens (tokens created by methods other than
+///     <c>cancellation_token::none()</c>of the tasks supplied.
+/// </param>
+/// <returns>
+///     A task that completes sucessfully when all of the input tasks have completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;&gt;</c>. If the input tasks are of type <c>void</c> the output
+///     task will also be a <c>task&lt;void&gt;</c>.
+/// </returns>
+/// <remarks>
+///     If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception,
+///     if one is encoutered, will be thrown if you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template <typename _Iterator>
+#if _MSC_VER >= 1800
+auto when_all(_Iterator _Begin, _Iterator _End, const task_options& _TaskOptions = task_options())
+-> decltype (details::_WhenAllImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_TaskOptions, _Begin, _End))
+{
+    typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
+    return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(_TaskOptions, _Begin, _End);
+}
+#else
+auto when_all(_Iterator _Begin, _Iterator _End, Concurrency::cancellation_token _CancellationToken)
+-> decltype (details::_WhenAllImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End))
+{
+    typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
+    return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End);
+}
+#endif
 
-        _ContextCallback _M_progressDelegateContext;
-        typename _Attributes::_ProgressDelegateType* _M_progressDelegate;
-    };
+/// <summary>
+///     Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;&gt;</c>. If the input tasks are of type <c>void</c> the output
+///     task will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA &amp;&amp; taskB &amp;&amp; taskC, which are combined in pairs, the &amp;&amp; operator
+///     produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if either one or both of the tasks are of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>.</para>
+/// </returns>
+/// <remarks>
+///     If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception,
+///     if one is encoutered, will be thrown if you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _ReturnType>
+task<std::vector<_ReturnType>> operator&&(const task<_ReturnType> & _Lhs, const task<_ReturnType> & _Rhs)
+{
+    task<_ReturnType> _PTasks[2] = { _Lhs, _Rhs };
+    return when_all(_PTasks, _PTasks + 2);
+}
 
-    template<typename _Attributes, _AsyncResultType _ResultType = SingleResult>
-    class _AsyncBaseProgressLayer abstract : public _AsyncProgressBase<_Attributes, _Attributes::_TakesProgress, _ResultType>
-    {
-    };
+/// <summary>
+///     Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;&gt;</c>. If the input tasks are of type <c>void</c> the output
+///     task will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA &amp;&amp; taskB &amp;&amp; taskC, which are combined in pairs, the &amp;&amp; operator
+///     produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if either one or both of the tasks are of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>.</para>
+/// </returns>
+/// <remarks>
+///     If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception,
+///     if one is encoutered, will be thrown if you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _ReturnType>
+task<std::vector<_ReturnType>> operator&&(const task<std::vector<_ReturnType>> & _Lhs, const task<_ReturnType> & _Rhs)
+{
+    return details::_WhenAllVectorAndValue(_Lhs, _Rhs, true);
+}
 
-    // ***************************************************************************
-    // Task Adaptation Layer:
-    //
+/// <summary>
+///     Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;&gt;</c>. If the input tasks are of type <c>void</c> the output
+///     task will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA &amp;&amp; taskB &amp;&amp; taskC, which are combined in pairs, the &amp;&amp; operator
+///     produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if either one or both of the tasks are of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>.</para>
+/// </returns>
+/// <remarks>
+///     If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception,
+///     if one is encoutered, will be thrown if you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _ReturnType>
+task<std::vector<_ReturnType>> operator&&(const task<_ReturnType> & _Lhs, const task<std::vector<_ReturnType>> & _Rhs)
+{
+    return details::_WhenAllVectorAndValue(_Rhs, _Lhs, false);
+}
 
-    //
-    // _AsyncTaskThunkBase provides a bridge between IAsync<Action/Operation> and task.
-    //
-    template<typename _Attributes, typename _ReturnType>
-    class _AsyncTaskThunkBase abstract : public _AsyncBaseProgressLayer<_Attributes>
-    {
-    public:
-        STDMETHODIMP GetResults(_ReturnType* results)
-        {
-            HRESULT hr = _CheckValidStateForResultsCall();
-            if (FAILED(hr)) return hr;
-            hr = _M_task.get();
-            if (SUCCEEDED(hr)) *results = _M_results;
-            return hr;
-        }
+/// <summary>
+///     Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;&gt;</c>. If the input tasks are of type <c>void</c> the output
+///     task will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA &amp;&amp; taskB &amp;&amp; taskC, which are combined in pairs, the &amp;&amp; operator
+///     produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if either one or both of the tasks are of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>.</para>
+/// </returns>
+/// <remarks>
+///     If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception,
+///     if one is encoutered, will be thrown if you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _ReturnType>
+task<std::vector<_ReturnType>> operator&&(const task<std::vector<_ReturnType>> & _Lhs, const task<std::vector<_ReturnType>> & _Rhs)
+{
+    task<std::vector<_ReturnType>> _PTasks[2] = { _Lhs, _Rhs };
+    return when_all(_PTasks, _PTasks + 2);
+}
 
-    public:
-        typedef task<HRESULT> _TaskType;
+/// <summary>
+///     Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;&gt;</c>. If the input tasks are of type <c>void</c> the output
+///     task will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA &amp;&amp; taskB &amp;&amp; taskC, which are combined in pairs, the &amp;&amp; operator
+///     produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if either one or both of the tasks are of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>.</para>
+/// </returns>
+/// <remarks>
+///     If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception,
+///     if one is encoutered, will be thrown if you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+inline task<void> operator&&(const task<void> & _Lhs, const task<void> & _Rhs)
+{
+    task<void> _PTasks[2] = { _Lhs, _Rhs };
+    return when_all(_PTasks, _PTasks + 2);
+}
 
-        _AsyncTaskThunkBase(const _TaskType& _Task)
-            : _M_task(_Task)
+namespace details
+{
+    // Helper struct for when_any operators to know when tasks have completed
+    template <typename _CompletionType>
+    struct _RunAnyParam
+    {
+        _RunAnyParam() : _M_completeCount(0), _M_numTasks(0), _M_exceptionRelatedToken(nullptr), _M_fHasExplicitToken(false)
         {
         }
-
-        _AsyncTaskThunkBase()
+        ~_RunAnyParam()
         {
+            if (Concurrency::details::_CancellationTokenState::_IsValid(_M_exceptionRelatedToken))
+                _M_exceptionRelatedToken->_Release();
         }
+        task_completion_event<_CompletionType>      _M_Completed;
+        Concurrency::cancellation_token_source                   _M_cancellationSource;
+        Concurrency::details::_CancellationTokenState*            _M_exceptionRelatedToken;
+        atomic_size_t         _M_completeCount;
+        size_t                                      _M_numTasks;
+        bool                                        _M_fHasExplicitToken;
+    };
 
-        void _SetTaskCreationAddressHint(void* _SourceAddressHint)
+    template<typename _CompletionType, typename _Function, typename _TaskType>
+    void _WhenAnyContinuationWrapper(_RunAnyParam<_CompletionType> * _PParam, const _Function & _Func, task<_TaskType>& _Task)
+    {
+        bool _IsTokenCancled = !_PParam->_M_fHasExplicitToken && _Task._GetImpl()->_M_pTokenState != Concurrency::details::_CancellationTokenState::_None() && _Task._GetImpl()->_M_pTokenState->_IsCanceled();
+        if (_Task._GetImpl()->_IsCompleted() && !_IsTokenCancled)
         {
-            if (!(std::is_same<_Attributes::_AsyncKind, _TypeSelectorAsyncTask>::value))
+            _Func();
+#if _MSC_VER >= 1800
+            if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#else
+            if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#endif
             {
-                // Overwrite the creation address with the return address of create_async unless the
-                // lambda returned a task. If the create async lambda returns a task, that task is reused and
-                // we want to preserve its creation address hint.
-                _M_task._SetTaskCreationAddressHint(_SourceAddressHint);
+                delete _PParam;
             }
         }
-        template <typename _Function>
-        void DoCreateTask(_Function _func)
-        {
-            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results);
-        }
-
-    protected:
-        virtual void _OnStart() override
+        else
         {
-            _M_task.then([=](_TaskType _Antecedent) {
-                try
-                {
-                    _Antecedent.get();
-                }
-                catch (Concurrency::task_canceled&)
-                {
-                    _TryTransitionToCancelled();
-                }
-                catch(IRestrictedErrorInfo*& _Ex)
+            _CONCRT_ASSERT(_Task._GetImpl()->_IsCanceled() || _IsTokenCancled);
+            if (_Task._GetImpl()->_HasUserException() && !_IsTokenCancled)
+            {
+                if (_PParam->_M_Completed._StoreException(_Task._GetImpl()->_GetExceptionHolder()))
                 {
-                    HRESULT hr;
-                    HRESULT _hr;
-                    hr = _Ex->GetErrorDetails(NULL, &_hr, NULL, NULL);
-                    if (SUCCEEDED(hr)) hr = _hr;
-                    _TryTransitionToError(hr);
+                    // This can only enter once.
+                    _PParam->_M_exceptionRelatedToken = _Task._GetImpl()->_M_pTokenState;
+                    _CONCRT_ASSERT(_PParam->_M_exceptionRelatedToken);
+                    // Deref token will be done in the _PParam destructor.
+                    if (_PParam->_M_exceptionRelatedToken != Concurrency::details::_CancellationTokenState::_None())
+                    {
+                        _PParam->_M_exceptionRelatedToken->_Reference();
+                    }
                 }
-                catch (...)
+            }
+
+#if _MSC_VER >= 1800
+            if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#else
+            if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
+#endif
+            {
+                // If no one has be completed so far, we need to make some final cancellation decision.
+                if (!_PParam->_M_Completed._IsTriggered())
                 {
-                    _TryTransitionToError(E_FAIL);
+                    // If we already explicit token, we can skip the token join part.
+                    if (!_PParam->_M_fHasExplicitToken)
+                    {
+                        if (_PParam->_M_exceptionRelatedToken)
+                        {
+                            details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PParam->_M_exceptionRelatedToken);
+                        }
+                        else
+                        {
+                            // If haven't captured any exception token yet, there was no exception for all those tasks,
+                            // so just pick a random token (current one) for normal cancellation.
+                            details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Task._GetImpl()->_M_pTokenState);
+                        }
+                    }
+                    // Do exception cancellation or normal cancellation based on whether it has stored exception.
+                    _PParam->_M_Completed._Cancel();
                 }
-                _FireCompletion();
-            });
+                delete _PParam;
+            }
         }
+    }
 
-    protected:
-        _TaskType _M_task;
-        _ReturnType _M_results;
-        Concurrency::cancellation_token_source _M_cts;
-    };
-
-    template<typename _Attributes>
-    class _AsyncTaskThunkBase<_Attributes, void> abstract : public _AsyncBaseProgressLayer<_Attributes>
+    template<typename _ElementType, typename _Iterator>
+    struct _WhenAnyImpl
     {
-    public:
-        STDMETHODIMP GetResults()
-        {
-            HRESULT hr = _CheckValidStateForResultsCall();
-            if (FAILED(hr)) return hr;
-            hr = _M_task.get();
-            return hr;
-        }
-    public:
-        typedef task<HRESULT> _TaskType;
-
-        _AsyncTaskThunkBase(const _TaskType& _Task)
-            : _M_task(_Task)
-        {
-        }
-
-        _AsyncTaskThunkBase()
+#if _MSC_VER >= 1800
+        static task<std::pair<_ElementType, size_t>> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
+#else
+        static task<std::pair<_ElementType, size_t>> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
+#endif
         {
-        }
+            if (_Begin == _End)
+            {
+                throw Concurrency::invalid_operation("when_any(begin, end) cannot be called on an empty container.");
+            }
+#if _MSC_VER >= 1800
+            Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
+#endif
+            auto _PParam = new _RunAnyParam<std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *>>();
 
-        void _SetTaskCreationAddressHint(void* _SourceAddressHint)
-        {
-            if (!(std::is_same<_Attributes::_AsyncKind, _TypeSelectorAsyncTask>::value))
+            if (_PTokenState)
             {
-                // Overwrite the creation address with the return address of create_async unless the
-                // lambda returned a task. If the create async lambda returns a task, that task is reused and
-                // we want to preserve its creation address hint.
-                _M_task._SetTaskCreationAddressHint(_SourceAddressHint);
+                details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PTokenState);
+                _PParam->_M_fHasExplicitToken = true;
             }
-        }
-        template <typename _Function>
-        void DoCreateTask(_Function _func)
-        {
-            _M_task = _Attributes::_Generate_Task(_func, this, _M_cts);
-        }
-    protected:
-        virtual void _OnStart() override
-        {
-            _M_task.then([=](_TaskType _Antecedent) -> void {
-                try
-                {
-                    _Antecedent.get();
-                }
-                catch (Concurrency::task_canceled&)
+#if _MSC_VER >= 1800
+            task_options _Options(_TaskOptions);
+            _Options.set_cancellation_token(_PParam->_M_cancellationSource.get_token());
+            task<std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _Options);
+#else
+            task<std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
+            _Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true;
+#endif
+            // Keep a copy ref to the token source
+            auto _CancellationSource = _PParam->_M_cancellationSource;
+
+            _PParam->_M_numTasks = static_cast<size_t>(std::distance(_Begin, _End));
+            size_t index = 0;
+            for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
+            {
+                if (_PTask->is_apartment_aware())
                 {
-                    _TryTransitionToCancelled();
+                    _Any_tasks_completed._SetAsync();
                 }
-                catch (...)
+
+                _PTask->_Then([_PParam, index](task<_ElementType> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+                    auto _PParamCopy = _PParam; // Dev10
+                    auto _IndexCopy = index; // Dev10
+                    auto _Func = [&_ResultTask, _PParamCopy, _IndexCopy]() {
+                        _PParamCopy->_M_Completed.set(std::make_pair(std::make_pair(_ResultTask._GetImpl()->_GetResult(), _IndexCopy), _ResultTask._GetImpl()->_M_pTokenState));
+                    };
+#else
+                    auto _Func = [&_ResultTask, _PParam, index]() {
+                        _PParam->_M_Completed.set(std::make_pair(std::make_pair(_ResultTask._GetImpl()->_GetResult(), index), _ResultTask._GetImpl()->_M_pTokenState));
+                    };
+#endif
+                    _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
+                    return S_OK;
+#if _MSC_VER >= 1800
+                }, Concurrency::details::_CancellationTokenState::_None());
+#else
+                }, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+                index++;
+            }
+
+            // All _Any_tasks_completed._SetAsync() must be finished before this return continuation task being created.
+            return _Any_tasks_completed._Then([=](std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *> _Result, std::pair<_ElementType, size_t>* retVal) -> HRESULT {
+                _CONCRT_ASSERT(_Result.second);
+                if (!_PTokenState)
                 {
-                    _TryTransitionToError(E_FAIL);
+                    details::_JoinAllTokens_Add(_CancellationSource, _Result.second);
                 }
-                _FireCompletion();
-            });
+                *retVal = _Result.first;
+                return S_OK;
+#if _MSC_VER >= 1800
+            }, nullptr);
+#else
+            }, nullptr, true);
+#endif
         }
-
-    protected:
-        _TaskType _M_task;
-        Concurrency::cancellation_token_source _M_cts;
     };
 
-    template<typename _Attributes>
-    class _AsyncTaskThunk : public _AsyncTaskThunkBase<_Attributes, typename _Attributes::_ReturnType>
-    {
-    public:
+    template<typename _Iterator>
+    struct _WhenAnyImpl<void, _Iterator>
+    {
+#if _MSC_VER >= 1800
+        static task<size_t> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
+#else
+        static task<size_t> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
+#endif
+        {
+            if (_Begin == _End)
+            {
+                throw Concurrency::invalid_operation("when_any(begin, end) cannot be called on an empty container.");
+            }
+#if _MSC_VER >= 1800
+            Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
+#endif
+            auto _PParam = new _RunAnyParam<std::pair<size_t, Concurrency::details::_CancellationTokenState *>>();
+
+            if (_PTokenState)
+            {
+                details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PTokenState);
+                _PParam->_M_fHasExplicitToken = true;
+            }
 
-        _AsyncTaskThunk(const _TaskType& _Task) :
-            _AsyncTaskThunkBase(_Task)
-        {
-        }
+#if _MSC_VER >= 1800
+            task_options _Options(_TaskOptions);
+            _Options.set_cancellation_token(_PParam->_M_cancellationSource.get_token());
+            task<std::pair<size_t, _CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _Options);
+#else
+            task<std::pair<size_t, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
+#endif
+            // Keep a copy ref to the token source
+            auto _CancellationSource = _PParam->_M_cancellationSource;
 
-        _AsyncTaskThunk()
-        {
-        }
+            _PParam->_M_numTasks = static_cast<size_t>(std::distance(_Begin, _End));
+            size_t index = 0;
+            for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
+            {
+                if (_PTask->is_apartment_aware())
+                {
+                    _Any_tasks_completed._SetAsync();
+                }
 
-    protected:
+                _PTask->_Then([_PParam, index](task<void> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+                    auto _PParamCopy = _PParam; // Dev10
+                    auto _IndexCopy = index; // Dev10
+                    auto _Func = [&_ResultTask, _PParamCopy, _IndexCopy]() {
+                        _PParamCopy->_M_Completed.set(std::make_pair(_IndexCopy, _ResultTask._GetImpl()->_M_pTokenState));
+                    };
+#else
+                    auto _Func = [&_ResultTask, _PParam, index]() {
+                        _PParam->_M_Completed.set(std::make_pair(index, _ResultTask._GetImpl()->_M_pTokenState));
+                    };
+#endif
+                    _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
+                    return S_OK;
+#if _MSC_VER >= 1800
+                }, Concurrency::details::_CancellationTokenState::_None());
+#else
+                }, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
 
-        virtual void _OnClose() override
-        {
-        }
+                index++;
+            }
 
-        virtual void _OnCancel() override
-        {
-            _M_cts.cancel();
+            // All _Any_tasks_completed._SetAsync() must be finished before this return continuation task being created.
+            return _Any_tasks_completed._Then([=](std::pair<size_t, Concurrency::details::_CancellationTokenState *> _Result, size_t* retVal) -> HRESULT {
+                _CONCRT_ASSERT(_Result.second);
+                if (!_PTokenState)
+                {
+                    details::_JoinAllTokens_Add(_CancellationSource, _Result.second);
+                }
+                *retVal = _Result.first;
+                return S_OK;
+#if _MSC_VER >= 1800
+            }, nullptr);
+#else
+            }, nullptr, false);
+#endif
         }
     };
+} // namespace details
 
-    // ***************************************************************************
-    // Async Creation Layer:
-    //
-    template<typename _Function>
-    class _AsyncTaskGeneratorThunk : public _AsyncTaskThunk<typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes>
-    {
-    public:
+/// <summary>
+///     Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully.
+/// </summary>
+/// <typeparam name="_Iterator">
+///     The type of the input iterator.
+/// </typeparam>
+/// <param name="_Begin">
+///     The position of the first element in the range of elements to be combined into the resulting task.
+/// </param>
+/// <param name="_End">
+///     The position of the first element beyond the range of elements to be combined into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes successfully when any one of the input tasks has completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::pair&lt;T, size_t&gt;&gt;></c>, where the first element of the pair is the result
+///     of the completing task, and the second element is the index of the task that finished. If the input tasks are of type <c>void</c>
+///     the output is a <c>task&lt;size_t&gt;</c>, where the result is the index of the completing task.
+/// </returns>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _Iterator>
+#if _MSC_VER >= 1800
+auto when_any(_Iterator _Begin, _Iterator _End, const task_options& _TaskOptions = task_options())
+-> decltype (details::_WhenAnyImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_TaskOptions, _Begin, _End))
+{
+    typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
+    return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(_TaskOptions, _Begin, _End);
+}
+#else
+auto when_any(_Iterator _Begin, _Iterator _End)
+-> decltype (details::_WhenAnyImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(nullptr, _Begin, _End))
+{
+    typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
+    return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(nullptr, _Begin, _End);
+}
+#endif
 
-        typedef typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes _Attributes;
-        typedef typename _AsyncTaskThunk<_Attributes> _Base;
-        typedef typename _Attributes::_AsyncBaseType _AsyncBaseType;
+/// <summary>
+///     Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully.
+/// </summary>
+/// <typeparam name="_Iterator">
+///     The type of the input iterator.
+/// </typeparam>
+/// <param name="_Begin">
+///     The position of the first element in the range of elements to be combined into the resulting task.
+/// </param>
+/// <param name="_End">
+///     The position of the first element beyond the range of elements to be combined into the resulting task.
+/// </param>
+/// <param name="_CancellationToken">
+///     The cancellation token which controls cancellation of the returned task. If you do not provide a cancellation token, the resulting
+///     task will receive the cancellation token of the task that causes it to complete.
+/// </param>
+/// <returns>
+///     A task that completes successfully when any one of the input tasks has completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::pair&lt;T, size_t&gt;&gt;></c>, where the first element of the pair is the result
+///     of the completing task, and the second element is the index of the task that finished. If the input tasks are of type <c>void</c>
+///     the output is a <c>task&lt;size_t&gt;</c>, where the result is the index of the completing task.
+/// </returns>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _Iterator>
+auto when_any(_Iterator _Begin, _Iterator _End, Concurrency::cancellation_token _CancellationToken)
+-> decltype (details::_WhenAnyImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End))
+{
+    typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
+    return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End);
+}
 
-        _AsyncTaskGeneratorThunk(const _Function& _Func) : _M_func(_Func)
-        {
-            // Virtual call here is safe as the class is declared 'sealed'
-            _Start();
-        }
+/// <summary>
+///     Creates a task that will complete successfully when either of the tasks supplied as arguments completes successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;</c>. If the input tasks are of type <c>void</c> the output task
+///     will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA || taskB &amp;&amp; taskC, which are combined in pairs, with &amp;&amp; taking precedence
+///     over ||, the operator|| produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if one of the tasks is of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>
+///     and the other one is of type <c>task&lt;T&gt;.</para>
+/// </returns>
+/// <remarks>
+///     If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions,
+///     if any are encountered, will be thrown when you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _ReturnType>
+task<_ReturnType> operator||(const task<_ReturnType> & _Lhs, const task<_ReturnType> & _Rhs)
+{
+#if _MSC_VER >= 1800
+    auto _PParam = new details::_RunAnyParam<std::pair<_ReturnType, size_t>>();
+
+    task<std::pair<_ReturnType, size_t>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
+    // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called,
+    // So that _PParam can be used before it getting deleted.
+    auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<_ReturnType, size_t> _Ret, _ReturnType* retVal) -> HRESULT {
+        _CONCRT_ASSERT(_Ret.second);
+        details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, reinterpret_cast<Concurrency::details::_CancellationTokenState *>(_Ret.second));
+        *retVal = _Ret.first;
+        return S_OK;
+    }, nullptr);
+#else
+    auto _PParam = new details::_RunAnyParam<std::pair<_ReturnType, Concurrency::details::_CancellationTokenState *>>();
+
+    task<std::pair<_ReturnType, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
+    // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called,
+    // So that _PParam can be used before it getting deleted.
+    auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<_ReturnType, Concurrency::details::_CancellationTokenState *> _Ret, _ReturnType* retVal) -> HRESULT {
+        _CONCRT_ASSERT(_Ret.second);
+        details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second);
+        *retVal = _Ret.first;
+        return S_OK;
+    }, nullptr, false);
+#endif
+    if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware())
+    {
+        _ReturnTask._SetAsync();
+    }
 
-    protected:
+    _PParam->_M_numTasks = 2;
+    auto _Continuation = [_PParam](task<_ReturnType> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+        //  Dev10 compiler bug
+        auto _PParamCopy = _PParam;
+        auto _Func = [&_ResultTask, _PParamCopy]() {
+            _PParamCopy->_M_Completed.set(std::make_pair(_ResultTask._GetImpl()->_GetResult(), reinterpret_cast<size_t>(_ResultTask._GetImpl()->_M_pTokenState)));
+        };
+#else
+        auto _Func = [&_ResultTask, _PParam]() {
+            _PParam->_M_Completed.set(std::make_pair(_ResultTask._GetImpl()->_GetResult(), _ResultTask._GetImpl()->_M_pTokenState));
+        };
+#endif
+        _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
+        return S_OK;
+    };
 
-        //
-        // The only thing we must do different from the base class is we must spin the hot task on transition from Created->Started. Otherwise,
-        // let the base thunk handle everything.
-        //
+#if _MSC_VER >= 1800
+    _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
+    _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
+#else
+    _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
+    _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+    return _ReturnTask;
+}
 
-        virtual void _OnStart() override
-        {
-            //
-            // Call the appropriate task generator to actually produce a task of the expected type. This might adapt the user lambda for progress reports,
-            // wrap the return result in a task, or allow for direct return of a task depending on the form of the lambda.
-            //
-            DoCreateTask<_Function>(_M_func);
-            _Base::_OnStart();
-        }
+/// <summary>
+///     Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;</c>. If the input tasks are of type <c>void</c> the output task
+///     will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA || taskB &amp;&amp; taskC, which are combined in pairs, with &amp;&amp; taking precedence
+///     over ||, the operator|| produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if one of the tasks is of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>
+///     and the other one is of type <c>task&lt;T&gt;.</para>
+/// </returns>
+/// <remarks>
+///     If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions,
+///     if any are encountered, will be thrown when you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+template<typename _ReturnType>
+task<std::vector<_ReturnType>> operator||(const task<std::vector<_ReturnType>> & _Lhs, const task<_ReturnType> & _Rhs)
+{
+    auto _PParam = new details::_RunAnyParam<std::pair<std::vector<_ReturnType>, Concurrency::details::_CancellationTokenState *>>();
 
-        virtual void _OnCancel() override
-        {
-            _Base::_OnCancel();
-        }
+    task<std::pair<std::vector<_ReturnType>, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
+#if _MSC_VER < 1800
+    _Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true;
+#endif
+    // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called,
+    // So that _PParam can be used before it getting deleted.
+    auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<std::vector<_ReturnType>, Concurrency::details::_CancellationTokenState *> _Ret, std::vector<_ReturnType>* retVal) -> HRESULT {
+        _CONCRT_ASSERT(_Ret.second);
+        details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second);
+        *retVal = _Ret.first;
+        return S_OK;
+    }, nullptr, true);
+
+    if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware())
+    {
+        _ReturnTask._SetAsync();
+    }
 
-    private:
+    _PParam->_M_numTasks = 2;
+    _Lhs._Then([_PParam](task<std::vector<_ReturnType>> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+        //  Dev10 compiler bug
+        auto _PParamCopy = _PParam;
+        auto _Func = [&_ResultTask, _PParamCopy]() {
+            auto _Result = _ResultTask._GetImpl()->_GetResult();
+            _PParamCopy->_M_Completed.set(std::make_pair(_Result, _ResultTask._GetImpl()->_M_pTokenState));
+        };
+#else
+        auto _Func = [&_ResultTask, _PParam]() {
+            std::vector<_ReturnType> _Result = _ResultTask._GetImpl()->_GetResult();
+            _PParam->_M_Completed.set(std::make_pair(_Result, _ResultTask._GetImpl()->_M_pTokenState));
+        };
+#endif
+        _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
+        return S_OK;
+#if _MSC_VER >= 1800
+    }, Concurrency::details::_CancellationTokenState::_None());
+#else
+    }, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+    _Rhs._Then([_PParam](task<_ReturnType> _ResultTask) -> HRESULT {
+#if _MSC_VER >= 1800
+        //  Dev10 compiler bug
+        typedef _ReturnType _ReturnTypeDev10;
+        auto _PParamCopy = _PParam;
+        auto _Func = [&_ResultTask, _PParamCopy]() {
+            auto _Result = _ResultTask._GetImpl()->_GetResult();
+
+            std::vector<_ReturnTypeDev10> _Vec;
+            _Vec.push_back(_Result);
+            _PParamCopy->_M_Completed.set(std::make_pair(_Vec, _ResultTask._GetImpl()->_M_pTokenState));
+        };
+#else
+        auto _Func = [&_ResultTask, _PParam]() {
+            _ReturnType _Result = _ResultTask._GetImpl()->_GetResult();
 
-        _Function _M_func;
-    };
-} // namespace details
+            std::vector<_ReturnType> _Vec;
+            _Vec.push_back(_Result);
+            _PParam->_M_Completed.set(std::make_pair(_Vec, _ResultTask._GetImpl()->_M_pTokenState));
+        };
+#endif
+        _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
+        return S_OK;
+#if _MSC_VER >= 1800
+    }, Concurrency::details::_CancellationTokenState::_None());
+#else
+    }, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+    return _ReturnTask;
+}
 
 /// <summary>
-///     Creates a Windows Runtime asynchronous construct based on a user supplied lambda or function object. The return type of <c>create_async</c> is
-///     one of either <c>IAsyncAction^</c>, <c>IAsyncActionWithProgress&lt;TProgress&gt;^</c>, <c>IAsyncOperation&lt;TResult&gt;^</c>, or
-///     <c>IAsyncOperationWithProgress&lt;TResult, TProgress&gt;^</c> based on the signature of the lambda passed to the method.
+///     Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully.
 /// </summary>
-/// <param name="_Func">
-///     The lambda or function object from which to create a Windows Runtime asynchronous construct.
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
 /// </param>
 /// <returns>
-///     An asynchronous construct represented by an IAsyncAction^, IAsyncActionWithProgress&lt;TProgress&gt;^, IAsyncOperation&lt;TResult&gt;^, or an
-///     IAsyncOperationWithProgress&lt;TResult, TProgress&gt;^. The interface returned depends on the signature of the lambda passed into the function.
+///     A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;</c>. If the input tasks are of type <c>void</c> the output task
+///     will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA || taskB &amp;&amp; taskC, which are combined in pairs, with &amp;&amp; taking precedence
+///     over ||, the operator|| produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if one of the tasks is of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>
+///     and the other one is of type <c>task&lt;T&gt;.</para>
 /// </returns>
 /// <remarks>
-///     The return type of the lambda determines whether the construct is an action or an operation.
-///     <para>Lambdas that return void cause the creation of actions. Lambdas that return a result of type <c>TResult</c> cause the creation of
-///     operations of TResult.</para>
-///     <para>The lambda may also return a <c>task&lt;TResult&gt;</c> which encapsulates the aysnchronous work within itself or is the continuation of
-///     a chain of tasks that represent the asynchronous work. In this case, the lambda itself is executed inline, since the tasks are the ones that
-///     execute asynchronously, and the return type of the lambda is unwrapped to produce the asynchronous construct returned by <c>create_async</c>.
-///     This implies that a lambda that returns a task&lt;void&gt; will cause the creation of actions, and a lambda that returns a task&lt;TResult&gt; will
-///     cause the creation of operations of TResult.</para>
-///     <para>The lambda may take either zero, one or two arguments. The valid arguments are <c>progress_reporter&lt;TProgress&gt;</c> and
-///     <c>cancellation_token</c>, in that order if both are used. A lambda without arguments causes the creation of an asynchronous construct without
-///     the capability for progress reporting. A lambda that takes a progress_reporter&lt;TProgress&gt; will cause <c>create_async</c> to return an asynchronous
-///     construct which reports progress of type TProgress each time the <c>report</c> method of the progress_reporter object is called. A lambda that
-///     takes a cancellation_token may use that token to check for cancellation, or pass it to tasks that it creates so that cancellation of the
-///     asynchronous construct causes cancellation of those tasks.</para>
-///     <para>If the body of the lambda or function object returns a result (and not a task&lt;TResult&gt;), the lamdba will be executed
-///     asynchronously within the process MTA in the context of a task the Runtime implicitly creates for it. The <c>IAsyncInfo::Cancel</c> method will
-///     cause cancellation of the implicit task.</para>
-///     <para>If the body of the lambda returns a task, the lamba executes inline, and by declaring the lambda to take an argument of type
-///     <c>cancellation_token</c> you can trigger cancellation of any tasks you create within the lambda by passing that token in when you create them.
-///     You may also use the <c>register_callback</c> method on the token to cause the Runtime to invoke a callback when you call <c>IAsyncInfo::Cancel</c> on
-///     the async operation or action produced..</para>
-///     <para>This function is only available to Windows Store apps.</para>
+///     If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions,
+///     if any are encountered, will be thrown when you call <c>get()</c> or <c>wait()</c> on that task.
 /// </remarks>
-/// <seealso cref="task Class"/>
-/// <seealso cref="progress_reporter Class"/>
-/// <seealso cref="cancelation_token Class"/>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
 /**/
-template<typename _Function>
-__declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result
-details::_AsyncTaskGeneratorThunk<_Function>* create_async(const _Function& _Func)
+template<typename _ReturnType>
+task<std::vector<_ReturnType>> operator||(const task<_ReturnType> & _Lhs, const task<std::vector<_ReturnType>> & _Rhs)
 {
-    static_assert(std::is_same<decltype(details::_IsValidCreateAsync(_Func, 0, 0, 0, 0)), std::true_type>::value,
-        "argument to create_async must be a callable object taking zero, one or two arguments");
-    Microsoft::WRL::ComPtr<details::_AsyncTaskGeneratorThunk<_Function>> _AsyncInfo = Microsoft::WRL::Make<details::_AsyncTaskGeneratorThunk<_Function>>(_Func);
-    _AsyncInfo->_SetTaskCreationAddressHint(_ReturnAddress());
-    return _AsyncInfo.Detach();
+    return _Rhs || _Lhs;
+}
+
+/// <summary>
+///     Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully.
+/// </summary>
+/// <typeparam name="_ReturnType">
+///     The type of the returned task.
+/// </typeparam>
+/// <param name="_Lhs">
+///     The first task to combine into the resulting task.
+/// </param>
+/// <param name="_Rhs">
+///     The second task to combine into the resulting task.
+/// </param>
+/// <returns>
+///     A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type <c>T</c>,
+///     the output of this function will be a <c>task&lt;std::vector&lt;T&gt;</c>. If the input tasks are of type <c>void</c> the output task
+///     will also be a <c>task&lt;void&gt;</c>.
+///     <para> To allow for a construct of the sort taskA || taskB &amp;&amp; taskC, which are combined in pairs, with &amp;&amp; taking precedence
+///     over ||, the operator|| produces a <c>task&lt;std::vector&lt;T&gt;&gt;</c> if one of the tasks is of type <c>task&lt;std::vector&lt;T&gt;&gt;</c>
+///     and the other one is of type <c>task&lt;T&gt;.</para>
+/// </returns>
+/// <remarks>
+///     If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions,
+///     if any are encountered, will be thrown when you call <c>get()</c> or <c>wait()</c> on that task.
+/// </remarks>
+/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
+/**/
+inline task<void> operator||(const task<void> & _Lhs, const task<void> & _Rhs)
+{
+    auto _PParam = new details::_RunAnyParam<std::pair<details::_Unit_type, Concurrency::details::_CancellationTokenState *>>();
+
+    task<std::pair<details::_Unit_type, Concurrency::details::_CancellationTokenState *>> _Any_task_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
+    // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called,
+    // So that _PParam can be used before it getting deleted.
+    auto _ReturnTask = _Any_task_completed._Then([=](std::pair<details::_Unit_type, Concurrency::details::_CancellationTokenState *> _Ret) -> HRESULT {
+        _CONCRT_ASSERT(_Ret.second);
+        details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second);
+        return S_OK;
+#if _MSC_VER >= 1800
+    }, nullptr);
+#else
+    }, nullptr, false);
+#endif
+
+    if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware())
+    {
+        _ReturnTask._SetAsync();
+    }
+
+    _PParam->_M_numTasks = 2;
+    auto _Continuation = [_PParam](task<void> _ResultTask) mutable -> HRESULT {
+        //  Dev10 compiler needs this.
+        auto _PParam1 = _PParam;
+        auto _Func = [&_ResultTask, _PParam1]() {
+            _PParam1->_M_Completed.set(std::make_pair(details::_Unit_type(), _ResultTask._GetImpl()->_M_pTokenState));
+        };
+        _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
+        return S_OK;
+    };
+
+#if _MSC_VER >= 1800
+    _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
+    _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
+#else
+    _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
+    _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
+#endif
+
+    return _ReturnTask;
+}
+
+#if _MSC_VER >= 1800
+template<typename _Ty>
+task<_Ty> task_from_result(_Ty _Param, const task_options& _TaskOptions = task_options())
+{
+    task_completion_event<_Ty> _Tce;
+    _Tce.set(_Param);
+    return create_task<_Ty>(_Tce, _TaskOptions);
+}
+
+// Work around VS 2010 compiler bug
+#if _MSC_VER == 1600
+inline task<bool> task_from_result(bool _Param)
+{
+    task_completion_event<bool> _Tce;
+    _Tce.set(_Param);
+    return create_task<bool>(_Tce, task_options());
+}
+#endif
+inline task<void> task_from_result(const task_options& _TaskOptions = task_options())
+{
+    task_completion_event<void> _Tce;
+    _Tce.set();
+    return create_task<void>(_Tce, _TaskOptions);
 }
+
+template<typename _TaskType, typename _ExType>
+task<_TaskType> task_from_exception(_ExType _Exception, const task_options& _TaskOptions = task_options())
+{
+    task_completion_event<_TaskType> _Tce;
+    _Tce.set_exception(_Exception);
+    return create_task<_TaskType>(_Tce, _TaskOptions);
+}
+
+namespace details
+{
+    /// <summary>
+    /// A convenient extension to Concurrency: loop until a condition is no longer met
+    /// </summary>
+    /// <param name="func">
+    ///   A function representing the body of the loop. It will be invoked at least once and
+    ///   then repetitively as long as it returns true.
+    /// </param>
+    inline
+    task<bool> do_while(std::function<task<bool>(void)> func)
+    {
+            task<bool> first = func();
+            return first.then([=](bool guard, task<bool>* retVal) -> HRESULT {
+                if (guard)
+                    *retVal = do_while(func);
+                else
+                    *retVal = first;
+                return S_OK;
+            });
+    }
+
+} // namespace details
+#endif
+
 } // namespace Concurrency_winrt
 
 namespace concurrency_winrt = Concurrency_winrt;
@@ -6331,3 +9462,5 @@ namespace concurrency_winrt = Concurrency_winrt;
 #pragma warning(pop)
 #pragma pack(pop)
 #endif
+
+#endif