public ExcelImportResult Process(
            BackgroundWorker bw)
        {
            using (var tfc = new TemporaryFileCloner(_information.SourceFilePath))
            {
                var dataSet = CoreExcelImporter.ImportExcelFromFile(tfc.FilePath);

                var result = new ExcelImportResult();

                var tableIndex = 0;
                foreach (DataTable table in dataSet.Tables)
                {
                    if (bw.CancellationPending)
                    {
                        throw new OperationCanceledException();
                    }

                    processTableFileIntelligent(
                        result,
                        tableIndex,
                        dataSet,
                        table,
                        bw);

                    tableIndex++;
                }

                return(result);
            }
        }
        public ExcelImportResult Process(
            BackgroundWorker bw)
        {
            using (var tfc = new TemporaryFileCloner(_information.SourceFilePath))
            {
                var dataSet = CoreExcelImporter.ImportExcelFromFile(tfc.FilePath);

                var result = new ExcelImportResult();

                var tableIndex = 0;
                foreach (DataTable table in dataSet.Tables)
                {
                    if (bw.CancellationPending)
                    {
                        throw new OperationCanceledException();
                    }

                    processTableFileIntelligent(
                        result,
                        tableIndex,
                        dataSet,
                        table,
                        bw);

                    tableIndex++;
                }

                return result;
            }
        }
        private void processTableFileIntelligent(
            ExcelImportResult result,
            int tableIndex,
            DataSet dataSet,
            DataTable table,
            BackgroundWorker bw)
        {
            var sourceRows = table.Rows;
            var sourceRowCount = table.Rows.Count;

            var checksumColumnIndex = getChecksumTableColumnIndex(table);
            var nameColumnIndex = getNameTableColumnIndex(table);

            int referenceLanguageColumnIndex;
            string referenceLanguageName;
            getReferenceLanguageTableColumnIndex(
                table,
                out referenceLanguageColumnIndex,
                out referenceLanguageName);

            var hasChecksumColumn = checksumColumnIndex >= 0;
            var hasNameColumn = nameColumnIndex >= 0;
            var hasReferenceLanguageColumn = referenceLanguageColumnIndex >= 0;

            // --

            var fgCache = new Dictionary<Guid, DBFileGroupCacheHelper>();

            for (var sourceRowIndex = 0; sourceRowIndex < sourceRowCount; ++sourceRowIndex)
            {
                // Need to process all file groups if not has any specified.
                var fileGroups =
                    _information.HasFileGroups
                        ? _information.FileGroups
                        : _information.Project.FileGroups.ToArray();

                foreach (var fileGroup in fileGroups)
                {
                    var checksum = fileGroup.GetChecksum(_information.Project);

                    // --

                    DBFileGroupCacheHelper ch;

                    if (!fgCache.TryGetValue(fileGroup.UniqueID, out ch))
                    {
                        ch = new DBFileGroupCacheHelper
                                {
                                    DB = new DataProcessing(fileGroup)
                                };

                        ch.Table = ch.DB.GetDataTableFromResxFiles(_information.Project);

                        fgCache[fileGroup.UniqueID] = ch;
                    }

                    // --

                    foreach (var languageCode in _information.LanguageCodes)
                    {
                        // UI progress and cancelation handling.
                        if ((sourceRowIndex + 1) % 20 == 0)
                        {
                            if (bw.CancellationPending)
                            {
                                throw new OperationCanceledException();
                            }

                            bw.ReportProgress(
                                0,
                                string.Format(
                                    Resources.SR_CommandProcessorReceive_Process_ProcessingWorkSheetOfRowOf,
                                    tableIndex + 1,
                                    dataSet.Tables.Count,
                                    sourceRowIndex + 1,
                                    sourceRowCount,
                                    (int)
                                    (((sourceRowIndex + 1.0) /
                                      (table.Rows.Count) *
                                      ((tableIndex + 1.0) /
                                       (dataSet.Tables.Count))) * 100)));
                        }

                        // --

                        var destinationTableColumnIndex =
                            getDestinationTableColumnIndex(
                                fileGroup.ParentSettings,
                                ch.Table,
                                languageCode);

                        // Column 0=FileGroup checksum, column 1=Tag name.
                        if (destinationTableColumnIndex > 1)
                        {
                            // We now have multiple possible options, based on the
                            // source lookup information provided. A maximum number
                            // of provided source information is:
                            //
                            //     - A file group checksum column.
                            //     - A name column.
                            //     - A reference language column.
                            //
                            // These information are calculated above. Decide now
                            // which actually to use.

                            var passedChecksum =
                                hasChecksumColumn &&
                                checksum == ConvertHelper.ToInt64(sourceRows[sourceRowIndex][checksumColumnIndex]) ||
                                !hasChecksumColumn;

                            if (passedChecksum)
                            {
                                List<DataRow> destinationRows;

                                if (hasNameColumn)
                                {
                                    var tagName =
                                        ConvertHelper.ToString(sourceRows[sourceRowIndex][nameColumnIndex]);

                                    if (string.IsNullOrEmpty(tagName))
                                    {
                                        // Skip empty table rows.
                                        destinationRows = null;
                                    }
                                    else
                                    {
                                        var destinationColumnIndex =
                                            getDestinationTableColumnIndex(
                                                fileGroup.ParentSettings,
                                                ch.Table,
                                                hasReferenceLanguageColumn
                                                    ? referenceLanguageName
                                                    : _information.Project.NeutralLanguageCode);

                                        destinationRows =
                                            getDestinationTableRowsByTagName(
                                                ch.Table,
                                                tagName,
                                                hasChecksumColumn,
                                                languageCode,
                                                destinationColumnIndex);
                                    }
                                }
                                else if (hasReferenceLanguageColumn)
                                {
                                    var refLanguageValue =
                                        ConvertHelper.ToString(
                                            sourceRows[sourceRowIndex][referenceLanguageColumnIndex]);

                                    if (string.IsNullOrEmpty(refLanguageValue))
                                    {
                                        // Skip empty table rows.
                                        destinationRows = null;
                                    }
                                    else
                                    {
                                        var refLanguageDestinationColumnIndex =
                                            getDestinationTableColumnIndex(
                                                fileGroup.ParentSettings,
                                                ch.Table,
                                                referenceLanguageName);

                                        // 2011-01-24, Uwe Keim:
                                        // If for one file, the language does not exist, simply skip.
                                        if (refLanguageDestinationColumnIndex < 0)
                                        {
                                            destinationRows = null;
                                        }
                                        else
                                        {
                                            destinationRows =
                                                getDestinationTableRowsByReferenceLanguageValue(
                                                    ch.Table,
                                                    refLanguageValue,
                                                    refLanguageDestinationColumnIndex,
                                                    hasChecksumColumn);
                                        }
                                    }
                                }
                                else
                                {
                                    throw new Exception(
                                        Resources.ExcelImportController_processWorkSheetFileIntelligent_Neither_name_column_nor_reference_language_column_present_);
                                }

                                // --

                                if (destinationRows != null && destinationRows.Count > 0)
                                {
                                    foreach (var row in destinationRows)
                                    {
                                        var tableSourceColumnIndex =
                                            getTableColumnIndex(table, languageCode);

                                        var sourceValue =
                                            ConvertHelper.ToString(
                                                sourceRows[sourceRowIndex][tableSourceColumnIndex],
                                                string.Empty);

                                        if (!string.IsNullOrEmpty(sourceValue))
                                        {
                                            var originalValue =
                                                ConvertHelper.ToString(
                                                    row[destinationTableColumnIndex],
                                                    string.Empty);

                                            if (originalValue != sourceValue)
                                            {
                                                row[destinationTableColumnIndex] = sourceValue;
                                                result.ImportedRowCount++;
                                                ch.HasAnychanges = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // --

            var saveCount = 0;
            var saveIndex = 0;

            // ReSharper disable LoopCanBeConvertedToQuery
            foreach (var p in fgCache)
            // ReSharper restore LoopCanBeConvertedToQuery
            {
                saveCount += p.Value.HasAnychanges ? 1 : 0;
            }

            foreach (var ch in fgCache)
            {
                if (ch.Value.HasAnychanges)
                {
                    bw.ReportProgress(
                        0,
                        string.Format(
                            Resources.ExcelImportController_processWorkSheetFileIntelligent_Saving_file__0__of__1____,
                            saveIndex + 1,
                            saveCount));

                    ch.Value.DB.SaveDataTableToResxFiles(_information.Project, ch.Value.Table);
                    saveIndex++;
                }
            }
        }
        private void processTableFileIntelligent(
            ExcelImportResult result,
            int tableIndex,
            DataSet dataSet,
            DataTable table,
            BackgroundWorker bw)
        {
            var sourceRows     = table.Rows;
            var sourceRowCount = table.Rows.Count;

            var checksumColumnIndex = getChecksumTableColumnIndex(table);
            var nameColumnIndex     = getNameTableColumnIndex(table);

            int    referenceLanguageColumnIndex;
            string referenceLanguageName;

            getReferenceLanguageTableColumnIndex(
                table,
                out referenceLanguageColumnIndex,
                out referenceLanguageName);

            var hasChecksumColumn          = checksumColumnIndex >= 0;
            var hasNameColumn              = nameColumnIndex >= 0;
            var hasReferenceLanguageColumn = referenceLanguageColumnIndex >= 0;

            // --

            var fgCache = new Dictionary <Guid, DBFileGroupCacheHelper>();

            for (var sourceRowIndex = 0; sourceRowIndex < sourceRowCount; ++sourceRowIndex)
            {
                // Need to process all file groups if not has any specified.
                var fileGroups =
                    _information.HasFileGroups
                        ? _information.FileGroups
                        : _information.Project.FileGroups.ToArray();

                foreach (var fileGroup in fileGroups)
                {
                    var checksum = fileGroup.GetChecksum(_information.Project);

                    // --

                    DBFileGroupCacheHelper ch;

                    if (!fgCache.TryGetValue(fileGroup.UniqueID, out ch))
                    {
                        ch = new DBFileGroupCacheHelper
                        {
                            DB = new DataProcessing(fileGroup)
                        };

                        ch.Table = ch.DB.GetDataTableFromResxFiles(_information.Project);

                        fgCache[fileGroup.UniqueID] = ch;
                    }

                    // --

                    foreach (var languageCode in _information.LanguageCodes)
                    {
                        // UI progress and cancelation handling.
                        if ((sourceRowIndex + 1) % 20 == 0)
                        {
                            if (bw.CancellationPending)
                            {
                                throw new OperationCanceledException();
                            }

                            bw.ReportProgress(
                                0,
                                string.Format(
                                    Resources.SR_CommandProcessorReceive_Process_ProcessingWorkSheetOfRowOf,
                                    tableIndex + 1,
                                    dataSet.Tables.Count,
                                    sourceRowIndex + 1,
                                    sourceRowCount,
                                    (int)
                                    (((sourceRowIndex + 1.0) /
                                      (table.Rows.Count) *
                                      ((tableIndex + 1.0) /
                                       (dataSet.Tables.Count))) * 100)));
                        }

                        // --

                        var destinationTableColumnIndex =
                            getDestinationTableColumnIndex(
                                fileGroup.ParentSettings,
                                ch.Table,
                                languageCode);

                        // Column 0=FileGroup checksum, column 1=Tag name.
                        if (destinationTableColumnIndex > 1)
                        {
                            // We now have multiple possible options, based on the
                            // source lookup information provided. A maximum number
                            // of provided source information is:
                            //
                            //     - A file group checksum column.
                            //     - A name column.
                            //     - A reference language column.
                            //
                            // These information are calculated above. Decide now
                            // which actually to use.

                            var passedChecksum =
                                hasChecksumColumn &&
                                checksum == ConvertHelper.ToInt64(sourceRows[sourceRowIndex][checksumColumnIndex]) ||
                                !hasChecksumColumn;

                            if (passedChecksum)
                            {
                                List <DataRow> destinationRows;

                                if (hasNameColumn)
                                {
                                    var tagName =
                                        ConvertHelper.ToString(sourceRows[sourceRowIndex][nameColumnIndex]);

                                    if (string.IsNullOrEmpty(tagName))
                                    {
                                        // Skip empty table rows.
                                        destinationRows = null;
                                    }
                                    else
                                    {
                                        var destinationColumnIndex =
                                            getDestinationTableColumnIndex(
                                                fileGroup.ParentSettings,
                                                ch.Table,
                                                hasReferenceLanguageColumn
                                                    ? referenceLanguageName
                                                    : _information.Project.NeutralLanguageCode);

                                        destinationRows =
                                            getDestinationTableRowsByTagName(
                                                ch.Table,
                                                tagName,
                                                hasChecksumColumn,
                                                languageCode,
                                                destinationColumnIndex);
                                    }
                                }
                                else if (hasReferenceLanguageColumn)
                                {
                                    var refLanguageValue =
                                        ConvertHelper.ToString(
                                            sourceRows[sourceRowIndex][referenceLanguageColumnIndex]);

                                    if (string.IsNullOrEmpty(refLanguageValue))
                                    {
                                        // Skip empty table rows.
                                        destinationRows = null;
                                    }
                                    else
                                    {
                                        var refLanguageDestinationColumnIndex =
                                            getDestinationTableColumnIndex(
                                                fileGroup.ParentSettings,
                                                ch.Table,
                                                referenceLanguageName);

                                        // 2011-01-24, Uwe Keim:
                                        // If for one file, the language does not exist, simply skip.
                                        if (refLanguageDestinationColumnIndex < 0)
                                        {
                                            destinationRows = null;
                                        }
                                        else
                                        {
                                            destinationRows =
                                                getDestinationTableRowsByReferenceLanguageValue(
                                                    ch.Table,
                                                    refLanguageValue,
                                                    refLanguageDestinationColumnIndex,
                                                    hasChecksumColumn);
                                        }
                                    }
                                }
                                else
                                {
                                    throw new Exception(
                                              Resources.ExcelImportController_processWorkSheetFileIntelligent_Neither_name_column_nor_reference_language_column_present_);
                                }

                                // --

                                if (destinationRows != null && destinationRows.Count > 0)
                                {
                                    foreach (var row in destinationRows)
                                    {
                                        var tableSourceColumnIndex =
                                            getTableColumnIndex(table, languageCode);

                                        var sourceValue =
                                            ConvertHelper.ToString(
                                                sourceRows[sourceRowIndex][tableSourceColumnIndex],
                                                string.Empty);

                                        if (!string.IsNullOrEmpty(sourceValue))
                                        {
                                            var originalValue =
                                                ConvertHelper.ToString(
                                                    row[destinationTableColumnIndex],
                                                    string.Empty);

                                            if (originalValue != sourceValue)
                                            {
                                                row[destinationTableColumnIndex] = sourceValue;
                                                result.ImportedRowCount++;
                                                ch.HasAnychanges = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // --

            var saveCount = 0;
            var saveIndex = 0;

            // ReSharper disable LoopCanBeConvertedToQuery
            foreach (var p in fgCache)
            // ReSharper restore LoopCanBeConvertedToQuery
            {
                saveCount += p.Value.HasAnychanges ? 1 : 0;
            }

            foreach (var ch in fgCache)
            {
                if (ch.Value.HasAnychanges)
                {
                    bw.ReportProgress(
                        0,
                        string.Format(
                            Resources.ExcelImportController_processWorkSheetFileIntelligent_Saving_file__0__of__1____,
                            saveIndex + 1,
                            saveCount));

                    ch.Value.DB.SaveDataTableToResxFiles(_information.Project, ch.Value.Table);
                    saveIndex++;
                }
            }
        }