public async Task Sync(DirectoryInfo source, string destination)
        {
            var filename = destination + "/" + HashStoreFilename;

            Log.Verbose("Creating hashes for current deployment...");
            var localFilesLookup = await FolderLookup.FromDirectory(source);

            Log.Verbose("Retrieving previous deployment hashes...");
            var remoteFilesLookup = await FolderLookup.FromFile(client, filename);

            var filesToCopy = GetFilesToCopy(localFilesLookup, remoteFilesLookup);

            var files = filesToCopy.Select(path => new FileInfo(Path.Join(source.FullName, path)));

            client.MirrorDirTree(source, destination);
            CopyFiles(source, files.ToList(), destination);

            SaveLocalLookup(localFilesLookup, filename);
        }
        private IEnumerable <string> GetFilesToCopy(FolderLookup local, FolderLookup remote)
        {
            var lookup = local.Concat(remote).ToLookup(x => x.Key, pair => pair.Value);

            var bothExist = lookup
                            .Where(pairs => pairs.Count() == 2);

            var hashMismatch = bothExist
                               .Where(hashes =>
            {
                var list       = hashes.ToList();
                var localHash  = list[0];
                var remoteHash = list[1];
                return(!localHash.SequenceEqual(remoteHash));
            })
                               .Select(x => x.Key);

            var localOnly   = local.Where(pair => !remote.ContainsKey(pair.Key)).Select(x => x.Key);
            var filesToCopy = hashMismatch.Concat(localOnly);

            return(filesToCopy);
        }