/// <exception cref="System.IO.IOException"></exception>
        public override IDictionary <string, Ref> GetRefs(string prefix)
        {
            RefList <Ref> packed = GetPackedRefs();
            RefList <RefDirectory.LooseRef> oldLoose = looseRefs.Get();

            RefDirectory.LooseScanner scan = new RefDirectory.LooseScanner(this, oldLoose);
            scan.Scan(prefix);
            RefList <RefDirectory.LooseRef> loose;

            if (scan.newLoose != null)
            {
                scan.newLoose.Sort();
                loose = scan.newLoose.ToRefList();
                if (looseRefs.CompareAndSet(oldLoose, loose))
                {
                    modCnt.IncrementAndGet();
                }
            }
            else
            {
                loose = oldLoose;
            }
            FireRefsChanged();
            RefListBuilder <Ref> symbolic = scan.symbolic;

            for (int idx = 0; idx < symbolic.Size();)
            {
                Ref symbolicRef = symbolic.Get(idx);
                Ref resolvedRef = Resolve(symbolicRef, 0, prefix, loose, packed);
                if (resolvedRef != null && resolvedRef.GetObjectId() != null)
                {
                    symbolic.Set(idx, resolvedRef);
                    idx++;
                }
                else
                {
                    // A broken symbolic reference, we have to drop it from the
                    // collections the client is about to receive. Should be a
                    // rare occurrence so pay a copy penalty.
                    symbolic.Remove(idx);
                    int toRemove = loose.Find(symbolicRef.GetName());
                    if (0 <= toRemove)
                    {
                        loose = loose.Remove(toRemove);
                    }
                }
            }
            symbolic.Sort();
            return(new RefMap(prefix, packed, Upcast(loose), symbolic.ToRefList()));
        }
        private RefList <RefDirectory.LooseRef> GetLooseRefs()
        {
            RefList <RefDirectory.LooseRef> oldLoose = looseRefs.Get();

            RefDirectory.LooseScanner scan = new RefDirectory.LooseScanner(this, oldLoose);
            scan.Scan(ALL);
            RefList <RefDirectory.LooseRef> loose;

            if (scan.newLoose != null)
            {
                loose = scan.newLoose.ToRefList();
                if (looseRefs.CompareAndSet(oldLoose, loose))
                {
                    modCnt.IncrementAndGet();
                }
            }
            else
            {
                loose = oldLoose;
            }
            return(loose);
        }