/// <summary>
        /// Create a diff file between the given first and second dump.
        /// </summary>
        /// <param name="firstDump">The first dump which is compared.</param>
        /// <param name="secondDump">The second dump which is compared.</param>
        /// <param name="diff">Location of the file.</param>
        public void CreateDiffFile(string firstDump, string secondDump, string diff)
        {
            if (!this.fileSystemAccess.FileExists(firstDump))
            {
                throw new FileNotFoundException(string.Format("Dump not found ({0})", firstDump));
            }

            if (!firstDump.Contains(SQLTemplates.DumpFile) ||
                !secondDump.Contains(SQLTemplates.DumpFile))
            {
                throw new TeamworkException(string.Format(
                                                "Wrong File type of dumps (previous: {0}) (actual: {1}). Need to be \"{2}\"",
                                                firstDump,
                                                secondDump,
                                                SQLTemplates.DumpFile));
            }

            // create diff file and throw exception if nothing changed
            if (!this.differenceCreator.Create(diff, this, firstDump, secondDump))
            {
                throw TeamworkException.NoChanges(firstDump, secondDump);
            }
        }
        /// <summary>
        /// Creates a dump file and compares it to the dump file of the old version.
        /// all changes will be written to a diff and undo diff file.
        /// </summary>
        public void Export(DatabaseVersion newVersion, string dumpCreatorPath, string host, string id, string password, int port)
        {
            lock (this.updateLock)
            {
                Log.Info($"Start exporting Database {this.Name}");
                this.SearchFiles(true);

                this.SetProgress(0, "Start the export");

                this.UpdateVersion();

                // file paths
                Log.Debug($"New Version for exported files is {newVersion}");

                var previousDump = this.CurrentDumpLocation;
                var dump         = this.GenerateFileLocation(newVersion, SQLTemplates.DumpFile);
                var diff         = this.GenerateFileLocation(newVersion, SQLTemplates.DiffFile);
                var undoDiff     = this.GenerateFileLocation(newVersion, SQLTemplates.UndoDiffFile);

                this.exporting = true;

                try
                {
                    // update version before creating dump, so the new dump contains the next version
                    this.SetProgress(10, "Creating a new dump");
                    this.CreateDump(dump, dumpCreatorPath, host, id, password, port);

                    if (this.fileSystemAccess.GetFileSize(previousDump) == this.fileSystemAccess.GetFileSize(dump))
                    {
                        // check files byte by byte
                        var oldDump = this.fileSystemAccess.ReadAllLines(previousDump);
                        var newDump = this.fileSystemAccess.ReadAllLines(dump);

                        if (oldDump.SequenceEqual(newDump))
                        {
                            throw TeamworkException.NoChanges(previousDump, dump);
                        }
                    }

                    // diff only original dumps
                    this.SetProgress(20, "Finding differences and creating files");
                    this.CreateDiffs(previousDump, dump, diff, undoDiff);

                    // test the new diff with all previous
                    this.TestSQLFiles(40, 100);
                    Log.Info(string.Format("Finished exporting version {0}", newVersion));
                }
                catch (TeamworkConnectionException ex)
                {
                    Log.Warn(string.Format("Error occured while testing exported files."), ex);
                    var message = $"Error occured in file [File] while testing exported files. Diff and Dump files will not be deleted and can be edited manually.Error: {ex.Message}";

                    if (ex.File != null)
                    {
                        message = message.Replace("[File]", ex.File.Path);
                        throw new TeamworkTestException(message, ex);
                    }

                    // do not delete files if only the test did not work => can be manually fixed by the user
                    message = message.Replace("[File]", "unknown");
                    throw new Exception(message, ex);
                }
                catch (Exception ex)
                {
                    Log.Error("Error occured while exporting new version", ex);

                    // delete new files if an error occured
                    if (this.fileSystemAccess.FileExists(dump))
                    {
                        this.fileSystemAccess.DeleteFile(dump);
                    }
                    if (this.fileSystemAccess.FileExists(diff))
                    {
                        this.fileSystemAccess.DeleteFile(diff);
                    }
                    if (this.fileSystemAccess.FileExists(undoDiff))
                    {
                        this.fileSystemAccess.DeleteFile(undoDiff);
                    }

                    if (newVersion == this.CurrentVersion)
                    {
                        this.ReduceVersion();
                    }

                    throw;
                }
                finally
                {
                    this.exporting = false;
                    this.SetProgress(100);
                }
            }

            this.UpdateData();
        }
        /// <summary>
        /// Undoes all changes which were made to this database by creating an undo diff and executing it.
        /// </summary>
        public void UndoChanges(string dumpCreatorPath, string host, string id, string password, int port)
        {
            Log.Info($"Start undoing Database {this.Name} to version {this.CurrentVersion}");

            // create undo diff
            this.SetProgress(0, "Start undoing changes");
            this.UpdateVersion();

            // file paths
            var previousDump = this.GenerateFileLocation(this.CurrentVersion, SQLTemplates.DumpFile);
            var dump         = this.GenerateFileLocation($"{DatabaseVersion.TempDumpName}{this.CurrentVersion}", SQLTemplates.DumpFile);
            var undoDiff     = this.GenerateFileLocation($"{DatabaseVersion.TempUndoDiffName}{this.CurrentVersion}", SQLTemplates.UndoDiffFile);

            try
            {
                // update version before creating dump, so the new dump contains the next version
                this.SetProgress(10, "Creating dump with changes which should be undone");
                this.CreateDump(dump, dumpCreatorPath, host, id, password, port);

                if (this.fileSystemAccess.GetFileSize(previousDump) == this.fileSystemAccess.GetFileSize(dump))
                {
                    // check files byte by byte
                    var oldDump = this.fileSystemAccess.ReadAllLines(previousDump);
                    var newDump = this.fileSystemAccess.ReadAllLines(dump);

                    if (oldDump.SequenceEqual(newDump))
                    {
                        throw TeamworkException.NoChanges(previousDump, dump);
                    }
                }

                // diff only original dumps
                this.SetProgress(20, "Finding differences and creating files");
                this.CreateDiffFile(dump, previousDump, undoDiff);

                // execute undo diff
                var file = new SQLFile(undoDiff, this, this.fileSystemAccess);
                file.ExecuteInTransaction();
            }
            catch (TeamworkConnectionException ex)
            {
                Log.Warn(string.Format("Error occured while testing exported files."), ex);
                var message = $"Error occured in file [File] while testing exported files. Diff and Dump files will not be deleted and can be edited manually.Error: {ex.Message}";

                if (ex.File != null)
                {
                    message = message.Replace("[File]", ex.File.Path);
                    throw new TeamworkTestException(message, ex);
                }

                // do not delete files if only the test did not work => can be manually fixed by the user
                message = message.Replace("[File]", "unknown");
                throw new Exception(message, ex);
            }
            catch (Exception ex)
            {
                Log.Error("Error occured while undoing changes", ex);
                throw;
            }
            finally
            {
                // remove undo diff and dump
                if (this.fileSystemAccess.FileExists(dump))
                {
                    this.fileSystemAccess.DeleteFile(dump);
                }

                if (this.fileSystemAccess.FileExists(undoDiff))
                {
                    this.fileSystemAccess.DeleteFile(undoDiff);
                }

                this.SetProgress(100);
            }
        }