private HgFile GetFileImpl(HgManifestFileEntry manifestFileEntry, HgNodeID filelogNodeID)
        {
            var filelog = GetFilelog(manifestFileEntry.Path);
            if(filelog == null) return null;

            var hgRevlogReader = Store.CreateRevlogReader(filelog.Revlog);
            var hgRevlogData = hgRevlogReader.ReadRevlogEntry(filelogNodeID);
            if(hgRevlogData == null) return null;

            //
            // Handle copyinfo and possibly other inband metadata. This part of Mercurial I don't like
            var data = hgRevlogData.Data;
            var copyInfo = HgFileCopyInfo.ExtractFileCopyInfo(ref data);

            log.Debug("retrieved file {0}@{1}", manifestFileEntry.Path.FullPath, filelogNodeID.Short);

            return new HgFile(manifestFileEntry.Path, hgRevlogData.Entry, data, copyInfo);
        }
        public HgFile GetFile(HgManifestFileEntry manifestFileEntry)
        {
            if(manifestFileEntry == null) return null;

            var filelogNodeID = manifestFileEntry.FilelogNodeID;
            return 
                HgRevlogBasedStorage.ObjectCache.
                    GetOrAdd(
                        string.Format("file:{0}@{1}", manifestFileEntry.Path.FullPath, filelogNodeID.Long),
                        () => GetFileImpl(manifestFileEntry, filelogNodeID));
        }