internal abstract Stream GetStream(VersionForRestore version);
 internal override Stream GetStream(VersionForRestore version)
 {
     return null;
 }
 private void Restore(FileSystemObject fso, VersionForRestore version, List<FileSystemObject> restoreLater)
 {
     version.Restore(fso, restoreLater);
 }
 internal override Stream GetStream(VersionForRestore version)
 {
     throw new NotImplementedException();
 }
        public void RestoreBackup()
        {
            VersionForRestore latestVersion = null;
            try
            {
                Console.WriteLine("Initializing structures...");
                {
                    var versions = new Dictionary<int, VersionForRestore>();
                    var stack = new Stack<int>();
                    var latestVersionNumber = Versions.Back();
                    stack.Push(latestVersionNumber);
                    while (stack.Count > 0)
                    {
                        var versionNumber = stack.Pop();
                        if (versions.ContainsKey(versionNumber))
                            continue;
                        var version = versions[versionNumber] = new VersionForRestore(versionNumber, this);
                        if (versionNumber == latestVersionNumber)
                            _oldObjects.AddRange(version.BaseObjects);
                        version.Manifest.VersionDependencies.ForEach(stack.Push);
                    }

                    latestVersion = versions[latestVersionNumber];
                    latestVersion.FillDependencies(versions);
                }

                var restoreLater = new List<FileSystemObject>();
                foreach (var fileSystemObject in _oldObjects)
                {
            // ReSharper disable once AccessToDisposedClosure
                    fileSystemObject.Iterate(x => Restore(x, latestVersion, restoreLater));
                }
                restoreLater.Sort((x, y) => x.StreamUniqueId < y.StreamUniqueId ? -1 : (x.StreamUniqueId > y.StreamUniqueId ? 1 : 0));
                foreach (var versionNumber in latestVersion.VersionNumber.ToEnumerable().Concat(latestVersion.Manifest.VersionDependencies))
                {
                    using (var archive = new ArchiveReader(GetVersionPath(versionNumber)))
                    {
                        archive.Begin((streamId, stream) =>
                        {
                            var index = restoreLater.BinaryFindFirst(x => x.StreamUniqueId >= streamId);
                            if (index >= restoreLater.Count)
                                return;
                            Console.WriteLine(@"Restoring path: ""{0}""", restoreLater[index].UnmappedPath);
                            var hardlink = restoreLater[index] as FileHardlinkFso;
                            if (hardlink != null)
                            {
                                hardlink.TreatAsFile = true;
                            }
                            restoreLater[index].Restore(stream);
                            for (int i = index + 1;
                                i < restoreLater.Count && restoreLater[i].StreamUniqueId == streamId;
                                i++)
                            {
                                Console.WriteLine(@"Hardlink requested. Existing path: ""{0}"", new path: ""{1}""", restoreLater[index].MappedPath, restoreLater[i].MappedPath);
                                hardlink = (FileHardlinkFso) restoreLater[i];
                                hardlink.Target = restoreLater[index].UnmappedPath;
                                hardlink.Restore();
                            }
                        });
                    }
                }
            }
            finally
            {
                if (latestVersion != null)
                    latestVersion.Dispose();
            }
        }