/// <exception cref="System.IO.IOException"></exception>
        public override Ref Peel(Ref @ref)
        {
            Ref leaf = @ref.GetLeaf();

            if (leaf.IsPeeled() || leaf.GetObjectId() == null)
            {
                return(@ref);
            }
            ObjectIdRef newLeaf = DoPeel(leaf);

            // Try to remember this peeling in the cache, so we don't have to do
            // it again in the future, but only if the reference is unchanged.
            if (leaf.GetStorage().IsLoose())
            {
                RefList <RefDirectory.LooseRef> curList = looseRefs.Get();
                int idx = curList.Find(leaf.GetName());
                if (0 <= idx && curList.Get(idx) == leaf)
                {
                    RefDirectory.LooseRef           asPeeled = ((RefDirectory.LooseRef)leaf).Peel(newLeaf);
                    RefList <RefDirectory.LooseRef> newList  = curList.Set(idx, asPeeled);
                    looseRefs.CompareAndSet(curList, newList);
                }
            }
            return(Recreate(@ref, newLeaf));
        }
        /// <exception cref="System.IO.IOException"></exception>
        private Ref ReadRef(string name, RefList <Ref> packed)
        {
            RefList <RefDirectory.LooseRef> curList = looseRefs.Get();
            int idx = curList.Find(name);

            if (0 <= idx)
            {
                RefDirectory.LooseRef o = curList.Get(idx);
                RefDirectory.LooseRef n = ScanRef(o, name);
                if (n == null)
                {
                    if (looseRefs.CompareAndSet(curList, curList.Remove(idx)))
                    {
                        modCnt.IncrementAndGet();
                    }
                    return(packed.Get(name));
                }
                if (o == n)
                {
                    return(n);
                }
                if (looseRefs.CompareAndSet(curList, curList.Set(idx, n)))
                {
                    modCnt.IncrementAndGet();
                }
                return(n);
            }
            RefDirectory.LooseRef n_1 = ScanRef(null, name);
            if (n_1 == null)
            {
                return(packed.Get(name));
            }
            // check whether the found new ref is the an additional ref. These refs
            // should not go into looseRefs
            for (int i = 0; i < additionalRefsNames.Length; i++)
            {
                if (name.Equals(additionalRefsNames[i]))
                {
                    return(n_1);
                }
            }
            if (looseRefs.CompareAndSet(curList, curList.Add(idx, n_1)))
            {
                modCnt.IncrementAndGet();
            }
            return(n_1);
        }