public async Task <Possible <CasHash, Failure> > AddToCasAsync(
            string filename,
            FileState fileState,
            CasHash?hash,
            UrgencyHint urgencyHint,
            Guid activityId)
        {
            using (var eventing = new AddToCasFilenameActivity(CompositingCache.EventSource, activityId, this))
            {
                eventing.Start(filename, fileState, urgencyHint);

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

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

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

            using (var counter = m_counters.AddToCasCounterFile())
            {
                using (var eventing = new AddToCasFilenameActivity(BasicFilesystemCache.EventSource, activityId, this))
                {
                    eventing.Start(filename, fileState, urgencyHint);

                    Possible <CasHash, Failure> result;

                    // First we need to do the hash of the file
                    // We do this "in place" since the CAS may be
                    // on "slow" storage and this is local
                    try
                    {
                        // We keep the file open during this such that others can't modify it
                        // until the add-to-cas has completed.  It also happens to be needed
                        // in order to compute the hash.
                        using (var fileData = await m_cache.ContendedOpenStreamAsync(filename, FileMode.Open, FileAccess.Read, FileShare.Read, handlePendingDelete: false))
                        {
                            counter.ContentSize(fileData.Length);

                            CasHash casHash = new CasHash(await ContentHashingUtilities.HashContentStreamAsync(fileData));

                            try
                            {
                                if (!await m_cache.AddToCasAsync(filename, 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, filename, e);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        counter.Failed();
                        result = new HashFailure(CacheId, filename, e);
                    }

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