public void DeleteSelectedFiles(MainForm mainForm, ImageListView imageListView, HashSet <FileEntry> fileEntries, bool deleteFromFileSystemAlso)
        {
            try
            {
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = true;
                ImageListViewHandler.SuspendLayout(imageListView);

                using (new WaitCursor())
                {
                    foreach (FileEntry fileEntry in fileEntries)
                    {
                        try
                        {
                            mainForm.UpdateStatusAction("Deleting the file " + fileEntry.FileFullPath + " and records in database");
                            if (deleteFromFileSystemAlso)
                            {
                                FileHandler.Delete(fileEntry.FileFullPath, Properties.Settings.Default.MoveToRecycleBin);
                            }
                            this.DeleteFileAndHistory(fileEntry.FileFullPath);
                            imageListView.Items.Remove(ImageListViewHandler.FindItem(imageListView.Items, fileEntry.FileFullPath));
                        }
                        catch (Exception ex)
                        {
                            KryptonMessageBox.Show("Was not able to delete the file: " + fileEntry.FileFullPath + "\r\n\r\n" + ex.Message,
                                                   "Deleting file failed", MessageBoxButtons.OK, MessageBoxIcon.Error, showCtrlCopy: true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                KryptonMessageBox.Show("Unexpected error occur.\r\nException message:" + ex.Message + "\r\n",
                                       "Unexpected error occur", MessageBoxButtons.OK, MessageBoxIcon.Error, showCtrlCopy: true);
            }
            finally
            {
                ImageListViewHandler.ResumeLayout(imageListView);
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = false;
            }
        }
        private void RenameFile_Thread_UpdateTreeViewFolderBrowser(TreeViewFolderBrowser folderTreeView, ImageListView imageListView, int renameQueueCount, string sourceFullFilename, string targetFullFilename)
        {
            if (InvokeRequired)
            {
                this.BeginInvoke(new Action <TreeViewFolderBrowser, ImageListView, int, string, string>(RenameFile_Thread_UpdateTreeViewFolderBrowser), folderTreeView, imageListView, renameQueueCount, sourceFullFilename, targetFullFilename);
                return;
            }

            try
            {
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = true;
                //ImageListViewHandler.SuspendLayout(imageListView1);

                using (new WaitCursor())
                {
                    try
                    {
                        bool directoryCreated = filesCutCopyPasteDrag.MoveFile(sourceFullFilename, targetFullFilename);

                        if (directoryCreated)
                        {
                            GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = true;
                            TreeViewFolderBrowserHandler.RefreshFolderWithName(folderTreeView, targetFullFilename, true);
                            GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = false;
                        }

                        ImageListViewItem foundItem = ImageListViewHandler.FindItem(imageListView.Items, sourceFullFilename);
                        if (foundItem != null)
                        {
                            ImageListViewHandler.ImageListViewRemoveItem(imageListView, foundItem);

                            #region Add new renames back to list
                            lock (keepTrackOfLoadedMetadataLock)
                            {
                                ImageListViewHandler.ImageListViewAddItem(imageListView1, targetFullFilename, ref hasTriggerLoadAllMetadataActions, ref keepTrackOfLoadedMetadata);
                            }
                            #endregion

                            #region Select back all Items renamed
                            foundItem = ImageListViewHandler.FindItem(imageListView.Items, targetFullFilename);
                            if (foundItem != null)
                            {
                                foundItem.Selected = true;
                            }
                            #endregion
                        }
                    }
                    catch (Exception ex)
                    {
                        #region Error Handling
                        DateTime dateTimeLastWriteTime = DateTime.Now;
                        try
                        {
                            dateTimeLastWriteTime = FileHandler.GetLastWriteTime(sourceFullFilename);
                        }
                        catch { }

                        FileStatus fileStatus = FileHandler.GetFileStatus(
                            sourceFullFilename, checkLockedStatus: true, hasErrorOccured: true, errorMessage: ex.Message);
                        ImageListView_UpdateItemFileStatusInvoke(sourceFullFilename, fileStatus);

                        FileStatus fileStatusTarget = FileHandler.GetFileStatus(
                            targetFullFilename, checkLockedStatus: true,
                            hasErrorOccured: true, errorMessage: ex.Message,
                            exiftoolProcessStatus: ExiftoolProcessStatus.DoNotUpdate);
                        ImageListView_UpdateItemFileStatusInvoke(targetFullFilename, fileStatus);

                        AddError(
                            Path.GetDirectoryName(sourceFullFilename),
                            Path.GetFileName(sourceFullFilename),
                            dateTimeLastWriteTime,
                            AddErrorFileSystemRegion, AddErrorFileSystemMove, sourceFullFilename, targetFullFilename,
                            "Issue: Failed moving file.\r\n" +
                            "From File name : " + sourceFullFilename + "\r\n" +
                            "From File staus: " + fileStatus.ToString() + "\r\n" +
                            "To   File name : " + targetFullFilename + "\r\n" +
                            "To   File staus: " + fileStatusTarget.ToString() + "\r\n" +
                            "Error message: " + ex.Message);
                        Logger.Error(ex, "Error when move file. From: " + sourceFullFilename + " to:" + targetFullFilename);
                        #endregion
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                KryptonMessageBox.Show("Unexpected error occur.\r\nException message:" + ex.Message + "\r\n",
                                       "Unexpected error occur", MessageBoxButtons.OK, MessageBoxIcon.Error, showCtrlCopy: true);
            }
            finally
            {
                //ImageListViewHandler.ResumeLayout(imageListView1);
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = false;
            }
            if (renameQueueCount == 0)
            {
                //To avoid selected files becomes added back to read queue, and also exist in rename queue,
                //that rename item can get removed after rename. With old name in read queue, and this file will then not exist when read
                ImageListView_SelectionChanged_Action_ImageListView_DataGridView(false);
            }
        }
        private void MoveFolder_UpdateTreeViewFolderBrowser(TreeViewFolderBrowser folderTreeView, string sourceDirectory, string targetDirectory, TreeNode targetNode)
        {
            if (sourceDirectory == targetDirectory)
            {
                return;                                     //Can't move into itself. No need for error message
            }
            try
            {
                using (new WaitCursor())
                {
                    FileData[] fileDatas = FastDirectoryEnumerator.GetFiles(sourceDirectory, "*.*", SearchOption.AllDirectories);

                    #region Move all folder and files
                    Logger.Trace("Move folder from:" + sourceDirectory + " to: " + targetDirectory);
                    System.IO.Directory.Move(sourceDirectory, targetDirectory);
                    #endregion

                    #region Clear ImageListView
                    ImageListViewHandler.ClearAllAndCaches(imageListView1);
                    #endregion

                    #region Update node tree
                    GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = true;
                    TreeViewFolderBrowserHandler.RefreshFolderWithName(folderTreeView, sourceDirectory, true);
                    TreeViewFolderBrowserHandler.RemoveFolderWithName(folderTreeView, sourceDirectory);
                    TreeViewFolderBrowserHandler.RefreshFolderWithName(folderTreeView, targetDirectory, true);
                    GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = false;
                    #endregion

                    #region Update database
                    foreach (FileData oldFileData in fileDatas)
                    {
                        string oldFilename     = Path.GetFileName(oldFileData.Path);
                        string newFullFilename = Path.Combine(targetDirectory, oldFilename);
                        Logger.Trace("Rename from:" + oldFileData.Path + " to: " + newFullFilename);

                        databaseAndCacheThumbnailPoster.Move(Path.GetDirectoryName(oldFileData.Path), Path.GetFileName(oldFileData.Path), Path.GetDirectoryName(newFullFilename), Path.GetFileName(newFullFilename));
                        databaseAndCacheMetadataExiftool.Move(Path.GetDirectoryName(oldFileData.Path), Path.GetFileName(oldFileData.Path), Path.GetDirectoryName(newFullFilename), Path.GetFileName(newFullFilename));
                    }
                    #endregion

                    DirectoryInfo directoryInfo        = new DirectoryInfo(sourceDirectory);
                    string        targetFullFolderName = targetDirectory + directoryInfo.Parent.Name;

                    GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = true;
                    treeViewFolderBrowser1.Populate(targetDirectory);
                    GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = false;
                }
                //----- Updated ImageListView with files ------
                ImageListView_FetchListOfMediaFiles_FromFolder_and_Aggregate(false, true);
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error when move folder.");

                AddError(
                    sourceDirectory,
                    AddErrorFileSystemRegion, AddErrorFileSystemMoveFolder, sourceDirectory, targetDirectory,
                    "Issue: Failed moving directory.\r\n" +
                    "From Directory: " + sourceDirectory + "\r\n" +
                    "To Directory: " + targetDirectory + "\r\n" +
                    "Error message: " + ex.Message);
            }
        }
        private void MoveFilesNoRename_UpdateTreeViewFolderBrowser(TreeViewFolderBrowser folderTreeView, ImageListView imageListView, StringCollection files, string targetNodeDirectory, TreeNode treeNodeTarget)
        {
            if (GlobalData.IsApplicationClosing)
            {
                return;
            }

            if (InvokeRequired)
            {
                this.BeginInvoke(new Action <TreeViewFolderBrowser, ImageListView, StringCollection, string, TreeNode>(MoveFilesNoRename_UpdateTreeViewFolderBrowser), folderTreeView, imageListView, files, targetNodeDirectory, treeNodeTarget);
                return;
            }

            if (GlobalData.IsApplicationClosing)
            {
                return;
            }

            if (DoNotTrigger_ImageListView_SelectionChanged())
            {
                return;
            }

            try
            {
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = true;

                ImageListViewHandler.SuspendLayout(imageListView1);

                #region Do the work
                using (new WaitCursor())
                {
                    foreach (string oldPath in files) //Move all files to target directory
                    {
                        string sourceFullFilename = oldPath;
                        string filename           = Path.GetFileName(sourceFullFilename);
                        string targetFullFilename = Path.Combine(targetNodeDirectory, filename);
                        try
                        {
                            bool directoryCreated = filesCutCopyPasteDrag.MoveFile(sourceFullFilename, targetFullFilename);

                            //------ Update node tree -----
                            GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = true;

                            if (treeNodeTarget == null)
                            {
                                string targetFolder = Path.GetDirectoryName(targetFullFilename);
                                TreeViewFolderBrowserHandler.RemoveFolderWithName(folderTreeView, targetFolder);
                            }
                            else
                            {
                                TreeViewFolderBrowserHandler.RefreshTreeNode(folderTreeView, treeNodeTarget);
                            }

                            GlobalData.DoNotTrigger_TreeViewFolder_BeforeAndAfterSelect = false;

                            ImageListViewItem foundItem = ImageListViewHandler.FindItem(imageListView.Items, sourceFullFilename);
                            if (foundItem != null)
                            {
                                ImageListViewHandler.ImageListViewRemoveItem(imageListView, foundItem);
                            }
                        }
                        catch (Exception ex)
                        {
                            DateTime dateTimeLastWriteTime = DateTime.Now;
                            try
                            {
                                dateTimeLastWriteTime = FileHandler.GetLastWriteTime(sourceFullFilename);
                            }
                            catch { }

                            FileStatus fileStatus = FileHandler.GetFileStatus(
                                sourceFullFilename, checkLockedStatus: true, hasErrorOccured: true, errorMessage: ex.Message);
                            ImageListView_UpdateItemFileStatusInvoke(sourceFullFilename, fileStatus);

                            FileStatus fileStatusTarget = FileHandler.GetFileStatus(
                                targetFullFilename, checkLockedStatus: true,
                                hasErrorOccured: true, errorMessage: ex.Message,
                                exiftoolProcessStatus: ExiftoolProcessStatus.DoNotUpdate);
                            ImageListView_UpdateItemFileStatusInvoke(targetFullFilename, fileStatus);

                            AddError(
                                Path.GetDirectoryName(sourceFullFilename),
                                Path.GetFileName(sourceFullFilename),
                                dateTimeLastWriteTime,
                                AddErrorFileSystemRegion, AddErrorFileSystemMove, sourceFullFilename, targetFullFilename,
                                "Issue: Failed moving file.\r\n" +
                                "From File name : " + sourceFullFilename + "\r\n" +
                                "From File staus: " + fileStatus.ToString() + "\r\n" +
                                "To   File name : " + targetFullFilename + "\r\n" +
                                "To   File staus: " + fileStatusTarget.ToString() + "\r\n" +
                                "Error message: " + ex.Message);

                            Logger.Error(ex, "Error when move file.");
                        }
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                KryptonMessageBox.Show("Unexpected error occur.\r\nException message:" + ex.Message + "\r\n",
                                       "Unexpected error occur", MessageBoxButtons.OK, MessageBoxIcon.Error, showCtrlCopy: true);
            }
            finally
            {
                GlobalData.IsPerformingAButtonAction = false;
                ImageListViewHandler.ResumeLayout(imageListView1);
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = false;

                ImageListView_SelectionChanged_Action_ImageListView_DataGridView(false);
            }
        }
        private void SelectedGroupByMatch(ImageListView imageListView,
                                          bool checkFileCreated, bool checkMediaTaken, bool checkAllDates, int maxDayRange,
                                          bool checkLocationName, bool checkLocationCity, bool checkLocationDistrict, bool checkLocationCountry, bool checkAllLocations)
        {
            try
            {
                ImageListViewHandler.SuspendLayout(imageListView1);
                ImageListViewHandler.Enable(imageListView, false);
                TreeViewFolderBrowserHandler.Enabled(treeViewFolderBrowser1, false);
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = true;

                #region Do the work
                using (new WaitCursor())
                {
                    ImageListViewItemCollection imageListViewItems = imageListView.Items;

                    List <GroupMacth> groupMacthSourceList = new List <GroupMacth>();


                    #region Init
                    foreach (ImageListViewItem imageListViewItem in imageListView.SelectedItems)
                    {
                        Metadata metadata = databaseAndCacheMetadataExiftool.ReadMetadataFromCacheOnly(new FileEntryBroker(imageListViewItem.FileFullPath, imageListViewItem.DateModified, MetadataBrokerType.ExifTool));

                        GroupMacth groupMacthSource = new GroupMacth();
                        groupMacthSource.IsMetadataNull   = (metadata == null);
                        groupMacthSource.FileDate         = imageListViewItem.Date;
                        groupMacthSource.MediaTaken       = metadata?.MediaDateTaken;
                        groupMacthSource.LocationName     = metadata?.LocationName;
                        groupMacthSource.LocationCity     = metadata?.LocationCity;
                        groupMacthSource.LocationDistrict = metadata?.LocationState;
                        groupMacthSource.LocationCountry  = metadata?.LocationCountry;
                        groupMacthSourceList.Add(groupMacthSource);
                    }
                    #endregion


                    imageListView.ClearSelection();

                    #region Find and Select
                    foreach (ImageListViewItem imageListViewItem in imageListView.Items)
                    {
                        Metadata metadata = databaseAndCacheMetadataExiftool.ReadMetadataFromCacheOnly(new FileEntryBroker(imageListViewItem.FileFullPath, imageListViewItem.DateModified, MetadataBrokerType.ExifTool));

                        GroupMacth groupMacthCheckWith = new GroupMacth();
                        groupMacthCheckWith.IsMetadataNull   = (metadata == null);
                        groupMacthCheckWith.FileDate         = imageListViewItem.Date;
                        groupMacthCheckWith.MediaTaken       = metadata?.MediaDateTaken;
                        groupMacthCheckWith.LocationName     = metadata?.LocationName;
                        groupMacthCheckWith.LocationCity     = metadata?.LocationCity;
                        groupMacthCheckWith.LocationDistrict = metadata?.LocationState;
                        groupMacthCheckWith.LocationCountry  = metadata?.LocationCountry;

                        bool isItemsEqual = false;

                        foreach (GroupMacth groupMacthSource in groupMacthSourceList)
                        {
                            isItemsEqual = GroupMacth.IsMatch(groupMacthSource, groupMacthCheckWith, checkFileCreated, checkMediaTaken,
                                                              checkAllDates, maxDayRange,
                                                              checkLocationName, checkLocationCity, checkLocationDistrict, checkLocationCountry, checkAllLocations);
                            if (isItemsEqual)
                            {
                                break;
                            }
                        }

                        if (isItemsEqual)
                        {
                            imageListViewItem.Selected = true;
                        }
                        else
                        {
                            imageListViewItem.Selected = false;
                        }
                    }
                    #endregion
                }
                #endregion
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                KryptonMessageBox.Show("Unexpected error occur.\r\nException message:" + ex.Message + "\r\n",
                                       "Unexpected error occur", MessageBoxButtons.OK, MessageBoxIcon.Error, showCtrlCopy: true);
            }
            finally
            {
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = false;
                TreeViewFolderBrowserHandler.Enabled(treeViewFolderBrowser1, true);
                ImageListViewHandler.Enable(imageListView, true);
                ImageListViewHandler.ResumeLayout(imageListView1);

                imageListView.Focus();

                ImageListView_SelectionChanged_Action_ImageListView_DataGridView(false);
            }
        }
        private void SelectedGroupBySelections(ImageListView imageListView, int baseItemIndex, int direction, int maxSelectCount,
                                               bool checkFileCreated, bool checkMediaTaken, bool checkAllDates, int maxDayRange,
                                               bool checkLocationName, bool checkLocationCity, bool checkLocationDistrict, bool checkLocationCountry, bool checkAllLocations)
        {
            try
            {
                ImageListViewHandler.SuspendLayout(imageListView1);
                ImageListViewHandler.Enable(imageListView, false);
                TreeViewFolderBrowserHandler.Enabled(treeViewFolderBrowser1, false);
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = true;

                #region Do the work
                using (new WaitCursor())
                {
                    ImageListViewItemCollection imageListViewItems = imageListView.Items;
                    if (baseItemIndex < imageListViewItems.Count && direction != 0)
                    {
                        #region Init Variables
                        GroupMacth groupMacthSource = new GroupMacth();

                        ImageListViewItem imageListViewItem = imageListViewItems[baseItemIndex];
                        Metadata          metadata          = databaseAndCacheMetadataExiftool.ReadMetadataFromCacheOnly(new FileEntryBroker(imageListViewItem.FileFullPath, imageListViewItem.DateModified, MetadataBrokerType.ExifTool));

                        groupMacthSource.IsMetadataNull   = (metadata == null);
                        groupMacthSource.FileDate         = imageListViewItem.Date;
                        groupMacthSource.MediaTaken       = metadata?.MediaDateTaken;
                        groupMacthSource.LocationName     = metadata?.LocationName;
                        groupMacthSource.LocationCity     = metadata?.LocationCity;
                        groupMacthSource.LocationDistrict = metadata?.LocationState;
                        groupMacthSource.LocationCountry  = metadata?.LocationCountry;
                        #endregion

                        imageListView.ClearSelection();

                        #region Find and Select
                        int selectedCount = 0;
                        int itemIndex     = baseItemIndex;
                        while (itemIndex > -1 && itemIndex < imageListViewItems.Count && selectedCount < maxSelectCount)
                        {
                            imageListViewItem = imageListViewItems[itemIndex];
                            metadata          = databaseAndCacheMetadataExiftool.ReadMetadataFromCacheOnly(new FileEntryBroker(imageListViewItem.FileFullPath, imageListViewItem.DateModified, MetadataBrokerType.ExifTool));

                            GroupMacth groupMacthCheckWith = new GroupMacth();
                            groupMacthCheckWith.IsMetadataNull   = (metadata == null);
                            groupMacthCheckWith.FileDate         = imageListViewItem.Date;
                            groupMacthCheckWith.MediaTaken       = metadata?.MediaDateTaken;
                            groupMacthCheckWith.LocationName     = metadata?.LocationName;
                            groupMacthCheckWith.LocationCity     = metadata?.LocationCity;
                            groupMacthCheckWith.LocationDistrict = metadata?.LocationState;
                            groupMacthCheckWith.LocationCountry  = metadata?.LocationCountry;


                            bool isItemsEqual = GroupMacth.IsMatch(groupMacthSource, groupMacthCheckWith, checkFileCreated, checkMediaTaken,
                                                                   checkAllDates, maxDayRange,
                                                                   checkLocationName, checkLocationCity, checkLocationDistrict, checkLocationCountry, checkAllLocations);

                            if (isItemsEqual)
                            {
                                selectedCount++;
                                imageListViewItem.Selected = true;
                            }
                            else
                            {
                                imageListViewItem.Selected = false;
                            }

                            itemIndex += direction;
                        }
                        #endregion

                        imageListView.EnsureVisible(itemIndex - direction);
                        imageListView.EnsureVisible(baseItemIndex);
                    }
                    lastGroupBaseIndex = baseItemIndex;
                }
                #endregion
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                KryptonMessageBox.Show("Unexpected error occur.\r\nException message:" + ex.Message + "\r\n",
                                       "Unexpected error occur", MessageBoxButtons.OK, MessageBoxIcon.Error, showCtrlCopy: true);
            }
            finally
            {
                GlobalData.DoNotTrigger_ImageListView_SelectionChanged = false;
                TreeViewFolderBrowserHandler.Enabled(treeViewFolderBrowser1, true);
                ImageListViewHandler.Enable(imageListView, true);
                ImageListViewHandler.ResumeLayout(imageListView1);

                imageListView.Focus();
                ImageListView_SelectionChanged_Action_ImageListView_DataGridView(false);
            }
        }