public void PerformActions()
        {
            Console.WriteLine();
            var actionsToPerform = _actionList.FindAll(x => x.ActionType != ActionType.None);

            if (actionsToPerform.Count == 0)
            {
                Console.WriteLine("No changes have been detected - no actions needed");
                return;
            }

            var syncWatch = new Stopwatch();

            syncWatch.Start();


            Console.WriteLine("Starting synchronization....");
            foreach (var action in actionsToPerform)
            {
                var          filesDict  = WorkingWithFiles.GetSourceAndDestFile(action.File1, action.File2);
                FileExtended sourceFile = filesDict[FileType.Source];
                FileExtended destFile   = filesDict[FileType.Destination];


                try
                {
                    switch (action.ActionType)
                    {
                    case ActionType.Create:
                        var creatingFileOp = action.ActionDirection == Direction.SourceToDestination
                                ? sourceFile.fullPath
                                : destFile.fullPath;
                        DisplaySyncProcessStats("Copying file " + creatingFileOp);
                        ActionCreate(sourceFile, destFile, action.ActionDirection);
                        _filesCreated++;

                        //Init.DisplayCompletionInfo("actions performed",
                        //    _filesCreated + _filesDeleted + _filesMoved + _filesRenamed + _filesRenamedMoved + _filesUpdated,
                        //    ActionsList.Count);
                        break;

                    case ActionType.Update:
                        var updatingFile = action.ActionDirection == Direction.SourceToDestination
                                ? destFile.fullPath
                                : sourceFile.fullPath;
                        DisplaySyncProcessStats("Updating file " + updatingFile);
                        ActionUpdate(sourceFile, destFile, action.ActionDirection);
                        _filesUpdated++;

                        break;

                    case ActionType.RenameMove:
                        var movingFile = action.ActionDirection == Direction.SourceToDestination
                                ? destFile.fullPath
                                : sourceFile.fullPath;
                        DisplaySyncProcessStats("Renaming and moving file " + movingFile);
                        ActionRenameMove(sourceFile, destFile, action.ActionDirection);
                        _filesRenamedMoved++;

                        break;

                    case ActionType.Rename:
                        var renamingFile = action.ActionDirection == Direction.SourceToDestination
                                ? destFile.fullPath
                                : sourceFile.fullPath;
                        DisplaySyncProcessStats("Renaming file " + renamingFile);
                        ActionRenameMove(sourceFile, destFile, action.ActionDirection);
                        _filesRenamed++;

                        break;

                    case ActionType.Move:
                        var movingFile2 = action.ActionDirection == Direction.SourceToDestination
                                ? destFile.fullPath
                                : sourceFile.fullPath;
                        DisplaySyncProcessStats("Renaming and moving file " + movingFile2);
                        ActionRenameMove(sourceFile, destFile, action.ActionDirection);
                        _filesMoved++;

                        break;

                        //case ActionType.Delete:
                        //    var archivingFile = action.ActionDirection == Direction.SourceToDestination
                        //        ? destFile.fullPath
                        //        : sourceFile.fullPath;
                        //    DisplaySyncProcessStats("Archiving file " + archivingFile);
                        //    ActionDelete(sourceFile, destFile, action.ActionDirection);
                        //    _filesDeleted++;

                        //    break;
                    }
                    action.SyncSuccess = true;
                }
                catch (Exception ex)
                {
                    action.SyncSuccess      = false;
                    action.ExceptionMessage = ex.Message;
                    _failedActions.Add(action);
                }
            }
            syncWatch.Stop();

            Console.WriteLine("\n\nSynchronization complete! Elapsed time: "
                              + Init.FormatTime(syncWatch.ElapsedMilliseconds));
        }
        public static void RemoveDuplicates(SyncExecution syncExec)
        {
            var w = new Stopwatch();

            w.Start();
            Console.WriteLine();
            Console.WriteLine("Checking for duplicate files...");

            var sourceFilesList = syncExec.SourceFiles.Values.ToList();
            var destFilesList   = syncExec.DestFiles.Values.ToList();

            ExcludeSomeFolders(sourceFilesList, syncExec.SyncConfig);
            ExcludeSomeFolders(destFilesList, syncExec.SyncConfig);

            sourceFilesList.Sort();
            destFilesList.Sort();

            var sourceFilesToProcess = new List <FileExtended>(sourceFilesList);
            var destFilesToProcess   = new List <FileExtended>(destFilesList);



            var duplSourceFiles = new List <FileExtended>()
            {
                Capacity = sourceFilesToProcess.Count
            };
            var duplDestFiles = new List <FileExtended>()
            {
                Capacity = destFilesToProcess.Count
            };

            CollectDuplicateFiles(sourceFilesToProcess, duplSourceFiles);
            CollectDuplicateFiles(destFilesToProcess, duplDestFiles);



            if (duplSourceFiles.Count == 0 && duplDestFiles.Count == 0)
            {
                Console.WriteLine("No duplicates have been found");
            }
            else
            {
                var duplSourceValues = duplSourceFiles
                                       .Select(x => x.FileNameAndSize)
                                       .Distinct()
                                       .ToList();
                var duplDestValues = duplDestFiles
                                     .Select(x => x.FileNameAndSize)
                                     .Distinct()
                                     .ToList();
                int duplSourceCount = duplSourceFiles.Count - duplSourceValues.Count;
                int duplDestCount   = duplDestFiles.Count - duplDestValues.Count;
                Console.WriteLine("Duplicates found: \n" +
                                  "\tsource files       " + duplSourceCount + "\n" +
                                  "\tdestination files  " + duplDestCount);

                Console.WriteLine("performing cleanup of source files...");
                CleanupDuplicateFiles(duplSourceFiles, FileType.Source, syncExec);

                Console.WriteLine("\nperforming cleanup of destination files...");
                CleanupDuplicateFiles(duplDestFiles, FileType.Destination, syncExec);
                Console.WriteLine("\nCleanup complete");
            }


            //WriteToLog(duplSourceFiles, duplDestFiles, logFile);

            w.Stop();
            Console.WriteLine("elapsed time: " + Init.FormatTime(w.ElapsedMilliseconds));
        }