private void AddFinalMatch(int tableRowIndex, int dataIndex, CompareRowResult rowResult, MatchQuality matchQuality)
        {
            // Missing TableRows are not added to final
            if (tableRowIndex != _tableRowsCount)
            {
                // A Match calls us to action.
                // We need to remove previous compares.
                // So, that when we finalize... Matches won't get confused with other Match Data
                for (int dataForIndex = 0; dataForIndex < _dataItemsCount; dataForIndex++)
                {
                    tableRowToDataCompares[tableRowIndex, dataForIndex] = null;
                }

                var tableRowCompareMatchResult = new CompareRowFinalResult();
                tableRowCompareMatchResult.compareRowResult   = rowResult;
                tableRowCompareMatchResult.matchQuality       = matchQuality;
                tableRowCompareMatchResult.index              = dataIndex;
                TableRowToDataCompareRowFinals[tableRowIndex] = tableRowCompareMatchResult;
            }

            // Missing Datas are not added to final
            if (dataIndex != _dataItemsCount)
            {
                for (int tableRowForIndex = 0; tableRowForIndex < _tableRowsCount; tableRowForIndex++)
                {
                    tableRowToDataCompares[tableRowForIndex, dataIndex] = null;
                }

                var dataCompareMatchResult = new CompareRowFinalResult();
                dataCompareMatchResult.compareRowResult   = rowResult;
                dataCompareMatchResult.matchQuality       = matchQuality;
                dataCompareMatchResult.index              = tableRowIndex;
                DataToTableRowCompareRowFinals[dataIndex] = dataCompareMatchResult;
            }
        }
        private void AddFinalMatch(int tableRowIndex, int dataIndex, CompareRowResult rowResult, MatchQuality matchQuality)
        {
            // Missing TableRows are not added to final
            if (tableRowIndex != _tableRowsCount)
            {
                // A Match calls us to action.
                // We need to remove previous compares.
                // So, that when we finalize... Matches won't get confused with other Match Data
                for (int dataForIndex = 0; dataForIndex < _dataItemsCount; dataForIndex++)
                {
                    tableRowToDataCompares[tableRowIndex, dataForIndex] = null;
                }

                var tableRowCompareMatchResult = new CompareRowFinalResult();
                tableRowCompareMatchResult.compareRowResult = rowResult;
                tableRowCompareMatchResult.matchQuality = matchQuality;
                tableRowCompareMatchResult.index = dataIndex;
                TableRowToDataCompareRowFinals[tableRowIndex] = tableRowCompareMatchResult;
            }

            // Missing Datas are not added to final
            if (dataIndex != _dataItemsCount)
            {
                for (int tableRowForIndex = 0; tableRowForIndex < _tableRowsCount; tableRowForIndex++)
                {
                    tableRowToDataCompares[tableRowForIndex, dataIndex] = null;
                }

                var dataCompareMatchResult = new CompareRowFinalResult();
                dataCompareMatchResult.compareRowResult = rowResult;
                dataCompareMatchResult.matchQuality = matchQuality;
                dataCompareMatchResult.index = tableRowIndex;
                DataToTableRowCompareRowFinals[dataIndex] = dataCompareMatchResult;
            }
        }
        private static void CompareRowResultToOutput(
            List<List<string>> output,
            char selfIdentifier,
            char matchIdentifier,
            CompareRowFinalResult[] compareRowFinals,
            Action<List<CompareColumnResult>, List<string>> columnPrinter
            )
        {
            for (int firstIndex = 0; firstIndex < compareRowFinals.Count(); firstIndex++)
            {
                var compareRowFinal = compareRowFinals[firstIndex];

                // # Identifier Column
                var outputLine = new List<string>();
                outputLine.Add(selfIdentifier + (firstIndex + 1).ToString());

                // Match Column
                if (compareRowFinal.matchQuality == MatchQuality.PerfectMatch)
                {
                    outputLine.Add(matchIdentifier + (compareRowFinal.index + 1).ToString());
                }
                else if (compareRowFinal.matchQuality == MatchQuality.Partial)
                {
                    outputLine.Add("? " + matchIdentifier + (compareRowFinal.index + 1).ToString());
                }
                else
                {
                    outputLine.Add(" ");
                }

                // Error Column
                if (compareRowFinal.matchQuality == MatchQuality.None)
                {
                    outputLine.Add("No Match");
                }
                else if (compareRowFinal.matchQuality == MatchQuality.PerfectMatch)
                {
                    var totalErrors = compareRowFinal.compareRowResult.totalErrors;
                    if (totalErrors != 0)
                    {
                        outputLine.Add(totalErrors.ToString() + " Columns");
                    }
                    else
                    {
                        outputLine.Add("perfect");
                    }
                }
                else
                {
                    // Partial
                    var totalErrors = compareRowFinal.compareRowResult.totalErrors;
                    if (totalErrors != 0)
                    {
                        outputLine.Add("Best " + totalErrors + " Columns");
                    }
                }

                columnPrinter(compareRowFinal.compareRowResult.columnResults, outputLine);

                output.Add(outputLine);
            }
        }