public async Task <Possible <CasHash, Failure> > AddToCasAsync(Stream filestream, CasHash?hash, UrgencyHint urgencyHint, Guid activityId)
        {
            using (var eventing = new AddToCasStreamActivity(CompositingCache.EventSource, activityId, this))
            {
                eventing.Start(filestream, urgencyHint);

                var result = await m_casSession.AddToCasAsync(filestream, hash, urgencyHint, eventing.Id);

                if (result.Succeeded)
                {
                    PinnedToCas.TryAdd(result.Result, 0);
                }

                return(eventing.Returns(result));
            }
        }
        public async Task <Possible <CasHash, Failure> > AddToCasAsync(Stream filestream, CasHash?hash, UrgencyHint urgencyHint, Guid activityId)
        {
            Contract.Requires(!IsClosed);
            Contract.Requires(filestream != null);

            Contract.Assert(!IsReadOnly);

            // We have this interesting issue - we are not sure if the stream is rewindable
            // and the target CAS may not be local so we will end up streaming this to
            // a temporary file just to pass it up.  (Implementation detail)
            using (var counter = m_counters.AddToCasCounterStream())
            {
                using (var eventing = new AddToCasStreamActivity(BasicFilesystemCache.EventSource, activityId, this))
                {
                    eventing.Start(filestream, urgencyHint);

                    Possible <CasHash, Failure> result;

                    string tmpFile = await m_cache.CreateTempFile();

                    // Since these are longer operations that are synchronous, we wrap them
                    // into a task for potential parallelism
                    try
                    {
                        CasHash casHash = await HashStreamToFileAsync(filestream, tmpFile);

                        try
                        {
                            counter.ContentSize(new FileInfo(tmpFile).Length);

                            if (!await m_cache.AddToCasAsync(tmpFile, casHash))
                            {
                                counter.DuplicatedContent();
                            }

                            // Pin it and return the hash
                            m_pinnedToCas.TryAdd(casHash, 0);

                            result = casHash;
                        }
                        catch (Exception e)
                        {
                            counter.Failed();
                            result = new AddToCasFailure(CacheId, casHash, "<stream>", e);
                        }
                    }
                    catch (Exception e)
                    {
                        counter.Failed();
                        result = new HashFailure(CacheId, "<stream>", e);
                    }
                    finally
                    {
                        try
                        {
                            File.Delete(tmpFile);
                        }
#pragma warning disable ERP022 // TODO: This should really handle specific errors
                        catch
                        {
                            // Ignore the failure - it is likely caused by
                            // a semantic breaking tool such as most virus scanners
                            // or disk indexers.  The file was a local teporary file
                            // in the temp directory
                        }
#pragma warning restore ERP022 // Unobserved exception in generic exception handler
                    }

                    return(eventing.Returns(result));
                }
            }
        }