private static Stream AsStreamInternalFactoryHelper(Object windowsRuntimeStream, Int32 bufferSize, String invokedMethodName, bool forceBufferSize)
        {
            Debug.Assert(windowsRuntimeStream != null);
            Debug.Assert(bufferSize >= 0);
            Debug.Assert(!String.IsNullOrWhiteSpace(invokedMethodName));

            Contract.Ensures(Contract.Result <Stream>() != null);
            Contract.EndContractBlock();

            // Get the adapter for this windowsRuntimeStream again (it may have been created concurrently).
            // If none exists yet, create a new one:
            Stream adapter = (bufferSize == 0)
                                ? WinRtToNetFxAdapterMap_GetValue(windowsRuntimeStream)
                                : WinRtToNetFxAdapterMap_GetValue(windowsRuntimeStream, bufferSize);

            Debug.Assert(adapter != null);
            Debug.Assert((adapter is BufferedStream && ((BufferedStream)adapter).UnderlyingStream is WinRtToNetFxStreamAdapter) ||
                         (adapter is WinRtToNetFxStreamAdapter));

            if (forceBufferSize)
            {
                EnsureAdapterBufferSize(adapter, bufferSize, invokedMethodName);
            }

            WinRtToNetFxStreamAdapter actualAdapter = adapter as WinRtToNetFxStreamAdapter;

            if (actualAdapter == null)
            {
                actualAdapter = ((BufferedStream)adapter).UnderlyingStream as WinRtToNetFxStreamAdapter;
            }

            actualAdapter.SetWonInitializationRace();

            return(adapter);
        }
        private static Object AsWindowsRuntimeStreamInternal(Stream stream)
        {
            Contract.Ensures(Contract.Result <Object>() != null);
            Contract.EndContractBlock();

            // Check to see if the managed stream is actually a wrapper of a WinRT stream:
            // (This can be either an adapter directly, or an adapter wrapped in a BufferedStream.)
            WinRtToNetFxStreamAdapter sAdptr = stream as WinRtToNetFxStreamAdapter;

            if (sAdptr == null)
            {
                BufferedStream buffAdptr = stream as BufferedStream;
                if (buffAdptr != null)
                {
                    sAdptr = buffAdptr.UnderlyingStream as WinRtToNetFxStreamAdapter;
                }
            }

            // If the managed stream us actually a WinRT stream, we will unwrap it and return the original.
            // In that case we do not need to put the wrapper into the map.
            if (sAdptr != null)
            {
                Object wrappedWinRtStream = sAdptr.GetWindowsRuntimeStream <Object>();
                if (wrappedWinRtStream == null)
                {
                    throw new ObjectDisposedException(nameof(stream), SR.ObjectDisposed_CannotPerformOperation);
                }

#if DEBUG  // In Chk builds, verify that the original WinRT stream is correctly entered into the WinRT->NetFx map:
                AssertMapContains(s_winRtToNetFxAdapterMap, wrappedWinRtStream, sAdptr, valueMayBeWrappedInBufferedStream: true);
#endif  // DEBUG
                return(wrappedWinRtStream);
            }

            // We have a real managed Stream.

            // See if the managed stream already has an adapter:
            NetFxToWinRtStreamAdapter adapter;
            bool adapterExists = s_netFxToWinRtAdapterMap.TryGetValue(stream, out adapter);

            // There is already an adapter:
            if (adapterExists)
            {
                return(adapter);
            }

            // We do not have an adapter for this managed stream yet and we need to create one.
            // Do that in a thread-safe manner in a separate method such that we only have to pay for the compiler allocating
            // the required closure if this code path is hit:
            return(AsWindowsRuntimeStreamInternalFactoryHelper(stream));
        }
 // Separate method so we only pay for closure allocation if this code is executed:
 private static Stream WinRtToNetFxAdapterMap_GetValue(Object winRtStream, Int32 bufferSize)
 {
     return(s_winRtToNetFxAdapterMap.GetValue(winRtStream, (wrtStr) => new BufferedStream(WinRtToNetFxStreamAdapter.Create(wrtStr), bufferSize)));
 }
 // Separate method so we only pay for closure allocation if this code is executed:
 private static Stream WinRtToNetFxAdapterMap_GetValue(Object winRtStream)
 {
     return(s_winRtToNetFxAdapterMap.GetValue(winRtStream, (wrtStr) => WinRtToNetFxStreamAdapter.Create(wrtStr)));
 }