private void HandleModifiesAndDeletes(VaultClientFolder folder, ChangeSetItemColl changes, bool isRepoRoot)
        {
            var diskPath = MakeDiskPath(folder.FullPath);

            if (!isRepoRoot && !Directory.Exists(diskPath))
            {
                changes.AddRange(ServerOperations.ProcessCommandDelete(new[] { folder.FullPath }));
                return;
            }

            HandleFiles(folder.Files, changes);
            foreach (VaultClientFolder subFolder in folder.Folders)
            {
                HandleModifiesAndDeletes(subFolder, changes, false);
            }
        }
        private static void HandleFiles(VaultClientFileColl fileColl, ChangeSetItemColl changes)
        {
            var diskPaths = fileColl.Cast <VaultClientFile>().Select(x => x.FullPath).ToList();
            var statuses  = ServerOperations.ProcessCommandStatus(diskPaths.ToArray());

            var pathAndStatus = diskPaths.Zip(statuses, Tuple.Create);

            foreach (var(path, status) in pathAndStatus)
            {
                switch (status)
                {
                case WorkingFolderFileStatus.None:
                case WorkingFolderFileStatus.Edited:
                    break;

                case WorkingFolderFileStatus.Missing:
                    changes.AddRange(ServerOperations.ProcessCommandDelete(new[] { path }));
                    Console.WriteLine($"Deleted {path} as it was {status}");
                    break;

                case WorkingFolderFileStatus.Renegade:
                    ServerOperations.ProcessCommandCheckout(new[] { path }, false, false, new GetOptions());
                    Console.WriteLine($"Checked out {path} as it was {status}");
                    break;

                case WorkingFolderFileStatus.Merged:
                case WorkingFolderFileStatus.NeedsMerge:
                case WorkingFolderFileStatus.Unknown:
                case WorkingFolderFileStatus.MoreRecent:
                case WorkingFolderFileStatus.Old:
                    Console.WriteLine($"Unhandled {path} with {status}");
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
        private void HandleAdds(VaultClientFolder folder, ChangeSetItemColl changes)
        {
            var versionedFiles = new HashSet <string>();

            GetAllVersionedFiles(folder, versionedFiles);
            var versionedDiskPaths = versionedFiles.Select(MakeDiskPath).ToList();

            var filesToAdd = new HashSet <string>(Directory.GetFiles(_workingFolder, "*", SearchOption.AllDirectories));

            filesToAdd.ExceptWith(versionedDiskPaths);

            var dirToFiles = new Dictionary <string, HashSet <string> >();

            foreach (var file in filesToAdd)
            {
                var dir = Path.GetDirectoryName(file);
                dir = dir.Substring(Math.Min(_workingFolder.Length + 1, dir.Length));
                if (!dirToFiles.TryGetValue(dir, out var files))
                {
                    files           = new HashSet <string>();
                    dirToFiles[dir] = files;
                }

                files.Add(file);
            }

            foreach (var pair in dirToFiles)
            {
                var dir   = pair.Key;
                var files = pair.Value;

                var repoFolder = string.IsNullOrEmpty(dir) ? _repoFolder : $"{_repoFolder}/{dir}";
                repoFolder = repoFolder.Replace('\\', '/');
                changes.AddRange(ServerOperations.ProcessCommandAdd(repoFolder, files.ToArray()));
            }
        }