//////////////////////////////////////////////////////////////////////////
        private string ProcessLine(int LineNum, string Line, FileToChange File)
        {
            string OutLine = Line;

            foreach (StringItem StrItem in File.Items)
            {
                if (StrItem.Line == LineNum)
                {
                    string OldString = "\"" + StrItem.OriginalString + "\"";

                    string NewString = StrItem.Value;
                    NewString = NewString.Replace("|", "~n");
                    NewString = NewString.Replace("\"", "~\"");
                    NewString = "\"/" + StrItem.ID + "/" + NewString + "\"";

                    if (OutLine.IndexOf(OldString) < 0)
                    {
                        AddLog("Cannot find original string " + OldString);
                        AddLog("(file: " + File.Filename + ", line: " + LineNum.ToString() + ")");
                    }
                    else
                    {
                        OutLine = OutLine.Replace(OldString, NewString);
                    }
                }
            }
            return(OutLine);
        }
        //////////////////////////////////////////////////////////////////////////
        private bool ProcessFile(FileToChange File)
        {
            try
            {
                if (this.BackupOldFiles)
                {
                    BackupFile(File.Filename);
                }

                Encoding      FileEncoding = Encoding.Default;
                List <string> Lines        = new List <string>();

                // read original file
                using (StreamReader sr = new StreamReader(File.Filename, Encoding.Default, true))
                {
                    string ReadLine;
                    int    LineNum = 0;
                    while ((ReadLine = sr.ReadLine()) != null)
                    {
                        LineNum++;
                        Lines.Add(ProcessLine(LineNum, ReadLine, File));
                    }
                    FileEncoding = sr.CurrentEncoding;
                }

                // save new file
                using (StreamWriter sw = new StreamWriter(File.Filename, false, FileEncoding))
                {
                    foreach (string Line in Lines)
                    {
                        sw.WriteLine(Line);
                    }
                }

                // mark items as saved ok
                foreach (StringItem Str in File.Items)
                {
                    Str.SavedOk = true;
                }

                return(true);
            }
            catch (Exception e)
            {
                AddLog("Error modifying file '" + File.Filename + "':");
                AddLog(e.Message);

                // mark items as NOT saved ok
                foreach (StringItem Str in File.Items)
                {
                    Str.SavedOk = false;
                }

                return(false);
            }
        }
        //////////////////////////////////////////////////////////////////////////
        public bool SaveChanges()
        {
            bool Ret = true;

            List <FileToChange> Files = new List <FileToChange>();

            AddLog("Preparing file list...");
            ReportProgress(0, 0, "Preparing file list...");
            foreach (StringItem StrItem in ProjectStrings)
            {
                if (StrItem.ID == string.Empty)
                {
                    continue;
                }

                FileToChange File;

                int Index = Files.BinarySearch(new FileToChange(StrItem.Filename));
                if (Index < 0)
                {
                    File = new FileToChange(StrItem.Filename);
                    Files.Add(File);
                    Files.Sort();
                }
                else
                {
                    File = Files[Index];
                }

                File.Items.Add(StrItem);
            }

            AddLog("Modifying files...");
            int CurrentFile = 0;

            foreach (FileToChange File in Files)
            {
                CurrentFile++;
                ReportProgress(CurrentFile, Files.Count, File.Filename);
                if (!ProcessFile(File))
                {
                    Ret = false;
                }
            }

            AddLog("Adding new items to string table...");
            ReportProgress(0, 0, "");
            if (!ProcessStringTable())
            {
                Ret = false;
            }


            if (Ret)
            {
                AddLog("Done.");
            }
            else
            {
                AddLog("Done with errors.");
            }
            ReportProgress(0, 0, "");

            return(Ret);
        }