/// <summary>
        /// Attempts to generate a merge row by taking all of the alterations made
        /// to the bioware row from the merge 2da's and incorporating them into 1
        /// row.  This will work unless 2 different 2da's change the same column
        /// in the row, which will make the merge fail.
        /// </summary>
        /// <param name="baseline">The bioware baseline 2da</param>
        /// <param name="list">The list of 2da's being merged</param>
        /// <param name="row">The row for which to generate a merge row</param>
        /// <returns>The merged row, or null if a merge row could not be
        /// generated.</returns>
        private StringCollection GenerateMergeRow(_2DA baseline, ArrayList list, int row)
        {
            try
            {
                // We cannot merge if the row is not in the baseline.
                if (row > baseline.Rows) return null;

                // Create a copy of the merge row in the baseline 2da.
                StringCollection resultRow = new StringCollection();
                StringCollection baselineRow = baseline.GetRowData(row);
                foreach (string s in baselineRow)
                    resultRow.Add(s);

                // Create a bool array to keep track of which columns
                // we modify.
                bool[] writtenTo = new bool[resultRow.Count];
                for (int i = 0; i < writtenTo.Length; i++)
                    writtenTo[i] = false;

                foreach (_2DA merge in list)
                {
                    // Get the row from the merge 2da.
                    StringCollection mergeRow = merge.GetRowData(row);

                    // If the collections do not have the same length then
                    // fail the merge, the added column may not be at the end.
                    if (mergeRow.Count != resultRow.Count) return null;

                    // Loop through all of the columns.
                    for (int i = 1; i < resultRow.Count; i++)
                    {
                        // Ignore empty data cells in the merge row.
                        if (_2DA.Empty == mergeRow[i]) continue;

                        // Compare the cell value against the baseline.  If it is the
                        // same then ignore it. (the result row starts out as the baseline
                        // so we do not need to set these values, and we need to ignore
                        // them to detect double writes to the same cell)
                        if (_2DA.CompareCell(baselineRow[i], mergeRow[i], true))
                            continue;

                        // Compare the cells from the result row and the merge row,
                        // if they are different then we need to copy the merge
                        // row's value into the result row.  However, if a previous
                        // merge 2da has modified this column then we have 2 different
                        // 2da's wanting non-bioware default values in the same
                        // column, if that happens there is no way to merge.
                        if (!_2DA.CompareCell(mergeRow[i], resultRow[i], true))
                        {
                            // If we've already changed the bioware default for this
                            // column we cannot merge return null.
                            if (writtenTo[i])
                                return null;
                            else
                            {
                                // Overwrite the bioware default for this column and
                                // save the fact that we have changed this column
                                resultRow[i] = mergeRow[i];
                                writtenTo[i] = true;
                            }
                        }
                    }
                }

                // If we get here we were able to take all of the various 2da
                // modifications to the bioware row and make 1 merge row with all
                // of the changes, return it.
                return resultRow;
            }
            catch (Exception)
            {
                return null;
            }
        }