/// <summary>
        /// todoComment
        /// </summary>
        /// <param name="ARow"></param>
        /// <param name="ALocationReUseKeyMapping"></param>
        /// <returns></returns>
        private static TLocationPK DetermineReplacedLocationPK(DataRow ARow, TLocationPK[, ] ALocationReUseKeyMapping)
        {
            TLocationPK ReturnValue;
            TLocationPK SubmittedLocationPK;
            Int64 SiteKey;
            Int32 LocationKey;
            int Counter;

            ReturnValue = null;
            SubmittedLocationPK = null;

            if (!((ARow is PLocationRow) || (ARow is PPartnerLocationRow)))
            {
                throw new System.ArgumentException("ARow Argument must be either of Type PLocationRow or of Type PPartnerLocationRow");
            }

            if (ARow is PLocationRow)
            {
                SiteKey = ((PLocationRow)ARow).SiteKey;
                LocationKey = (int)((PLocationRow)ARow).LocationKey;
            }
            else
            {
                SiteKey = ((PPartnerLocationRow)ARow).SiteKey;
                LocationKey = ((PPartnerLocationRow)ARow).LocationKey;
            }

            // Check if passed in Key can be found in the KeyMapping Array
            if ((ALocationReUseKeyMapping.GetLength(0) - 1) > 0)
            {
//              TLogging.LogAtLevel(9, "(Length(ALocationReUseKeyMapping): " + Convert.ToInt16(ALocationReUseKeyMapping.GetLength(0)).ToString());
                for (Counter = 1; Counter <= ALocationReUseKeyMapping.GetLength(0) - 1; Counter += 1)
                {
                    SubmittedLocationPK = ALocationReUseKeyMapping[Counter, 0];

                    if ((SubmittedLocationPK.LocationKey == LocationKey) && (SubmittedLocationPK.SiteKey == SiteKey))
                    {
                        // found passed in Key in the KeyMapping Array
                        ReturnValue = ALocationReUseKeyMapping[Counter, 1];
//                      TLogging.LogAtLevel(9, "DetermineReplacedLocationPK: Key found in Key Mapping.");
                        continue;
                    }
                }
            }

            if (ReturnValue == null)
            {
                // passed in Key not found in the KeyMapping Array
//              TLogging.LogAtLevel(9, "DetermineReplacedLocationPK: Key *not* found in Key Mapping");
                ReturnValue = new TLocationPK(SiteKey, LocationKey);
            }

//          TLogging.LogAtLevel(9, "DetermineReplacedLocationPK: ReturnValue.SiteKey: " + ReturnValue.SiteKey.ToString() + "; ReturnValue.LocationKey: " + ReturnValue.LocationKey.ToString());
            return ReturnValue;
        }
        /// <summary>
        /// todoComment
        /// </summary>
        private static TSubmitChangesResult PerformSimilarLocationReUseChecks(ref PLocationRow ALocationRow,
            ref PartnerAddressAggregateTDS AResponseDS,
            TDBTransaction ASubmitChangesTransaction,
            Int64 APartnerKey,
            ref PartnerAddressAggregateTDSSimilarLocationParametersTable AExistingLocationParametersDT,
            ref PPartnerLocationTable APartnerLocationTable,
            ref TLocationPK[, ] ALocationReUseKeyMapping,
            out Boolean AReUseSimilarLocation,
            ref TVerificationResultCollection AVerificationResult)
        {
            TSubmitChangesResult ReturnValue;
            PPartnerLocationRow PartnerLocationCheckRow;
            DataView ExistingLocationParametersDV;

            PLocationRow ExistingLocationRow;
            Int64 CurrentSiteKey;
            Int64 ExistingSiteKey;
            Int32 CurrentLocationKey;
            Int32 ExistingLocationKey;

            PLocationTable SimilarLocationDT;

//          TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AExistingLocationParametersDT.Rows.Count: " +
//              AExistingLocationParametersDT.Rows.Count.ToString());
            AReUseSimilarLocation = false;

            if (CheckReUseExistingLocation(ALocationRow, APartnerKey, ref AExistingLocationParametersDT, ASubmitChangesTransaction,
                    out ExistingSiteKey, out ExistingLocationKey))
            {
                // Check if there is a Parameter Row for the LocationKey we are looking at
                ExistingLocationParametersDV = new DataView(AExistingLocationParametersDT,
                    PartnerAddressAggregateTDSSimilarLocationParametersTable.GetSiteKeyDBName() + " = " + ALocationRow.SiteKey.ToString() + " AND " +
                    PartnerAddressAggregateTDSSimilarLocationParametersTable.GetLocationKeyDBName() + " = " + ALocationRow.LocationKey.ToString() +
                    " AND " + PartnerAddressAggregateTDSSimilarLocationParametersTable.GetAnswerProcessedClientSideDBName() + " = false",
                    "",
                    DataViewRowState.CurrentRows);

                if (ExistingLocationParametersDV.Count > 0)
                {
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Location " + ALocationRow.LocationKey.ToString() + ": found similar Location, decision is needed.");

                    /*
                     * More information is needed (usually via user interaction)
                     * -> stop processing here and return parameters
                     * (usually used for UI interaction)
                     */
                    if (AResponseDS == null)
                    {
//                      TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Creating AResponseDS.");
                        AResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET);
                    }

//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AExistingLocationParametersDT.Rows.Count: " + AExistingLocationParametersDT.Rows.Count.ToString());
                    AResponseDS.Merge(AExistingLocationParametersDT);
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Merged ExistingLocationParametersDT into AResponseDS.");
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AResponseDS.Tables[" + MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME +
//                            "].Rows.Count: " + AResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].Rows.Count.ToString());
                    return TSubmitChangesResult.scrInfoNeeded;
                }
                else
                {
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Location " + ALocationRow.LocationKey.ToString() +
//                      ": found similar Location and this one (" + ExistingLocationKey.ToString() + ") should be used instead of creating a new one!");

                    /*
                     * Location with the same data already exists and it should be
                     * re-used instead of creating a new one!
                     */

                    // Keep a mapping of the initially submitted LocationKey to the newly assigned one
                    ALocationReUseKeyMapping = new TLocationPK[ALocationReUseKeyMapping.GetLength(0) + 1, 2];
                    ALocationReUseKeyMapping[(ALocationReUseKeyMapping.GetLength(0)) - 1, 0] = new TLocationPK(ALocationRow.SiteKey,
                        (int)ALocationRow.LocationKey);
                    ALocationReUseKeyMapping[(ALocationReUseKeyMapping.GetLength(0)) - 1, 1] = new TLocationPK(ExistingSiteKey, ExistingLocationKey);
                    AReUseSimilarLocation = true;

                    if (!AExistingLocationParametersDT[0].AnswerProcessedServerSide)
                    {
                        AExistingLocationParametersDT[0].AnswerProcessedServerSide = true;

                        // Preserve Key of current Location
                        CurrentSiteKey = ALocationRow.SiteKey;
                        CurrentLocationKey = (int)ALocationRow.LocationKey;

                        /*
                         * Make sure that the Partner hasn't already got a PartnerLocation with
                         * the same Key (neither in memory nor in the DB)
                         */
//                      TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Finding PartnerLocation Row in APartnerLocationTable with LocationKey " + ALocationRow.LocationKey.ToString());
                        PartnerLocationCheckRow =
                            (PPartnerLocationRow)APartnerLocationTable.Rows.Find(new object[] { APartnerKey, ALocationRow.SiteKey,
                                                                                                ALocationRow.LocationKey });

                        if (PartnerLocationCheckRow != null)
                        {
                            /*
                             * Checks in Memory: look for Current (ie. unchanged, new or edited)
                             * rows first whether they are the Location that is about to being
                             * reused. Secondly, check if there is a deleted Location with the same
                             * LocationKey that is about to being reused; only if this is not the
                             * case:
                             * Check in the DB whether the Partner hasn't got the Location
                             * with the same LocationKey that is about to being reuse.
                             */
                            if ((APartnerLocationTable.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() +
                                     " AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = " + ExistingSiteKey.ToString() + " AND " +
                                     PPartnerLocationTable.GetLocationKeyDBName() + " = " + ExistingLocationKey.ToString(), "",
                                     DataViewRowState.CurrentRows).Length != 0)
                                || ((APartnerLocationTable.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() +
                                         " AND " +
                                         PPartnerLocationTable.GetSiteKeyDBName() + " = " + ExistingSiteKey.ToString() + " AND " +
                                         PPartnerLocationTable.GetLocationKeyDBName() + " = " + ExistingLocationKey.ToString(), "",
                                         DataViewRowState.Deleted).Length == 0)
                                    && (PPartnerLocationAccess.Exists(APartnerKey, ExistingSiteKey, ExistingLocationKey,
                                            ASubmitChangesTransaction))))
                            {
                                AVerificationResult.Add(new TVerificationResult("[Partner Address Save]", "Partner " + APartnerKey.ToString() +
                                        " already has a " + "record linked with Location " + ExistingLocationKey.ToString() + Environment.NewLine +
                                        "Unable to save.", "Duplicate Address Entered", "", TResultSeverity.Resv_Critical));
                                ReturnValue = TSubmitChangesResult.scrError;
                                return ReturnValue;
                            }
                            else
                            {
//                              TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: LocationKey: " + ExistingLocationKey.ToString() + " will later get assigned to PPartnerLocation.");
                            }
                        }
                        else
                        {
                            throw new EOPAppException(
                                "PerformSimilarLocationReUseChecks: PartnerLocationCheckRow with SiteKey " + ALocationRow.SiteKey.ToString() +
                                " and LocationKey " +
                                ALocationRow.LocationKey.ToString() + " not found!");
                        }

                        /*
                         * Copy all fields from the existing Location to the current Location
                         */
                        SimilarLocationDT = PLocationAccess.LoadByPrimaryKey(ExistingSiteKey, ExistingLocationKey, null, ASubmitChangesTransaction);

                        if (SimilarLocationDT.Rows.Count != 0)
                        {
                            ExistingLocationRow = (PLocationRow)SimilarLocationDT.Rows[0];

                            ALocationRow.ItemArray = ExistingLocationRow.ItemArray;

                            /*
                             * NOTE: The SiteKey and LocationKey are re-assigned to the ones of the
                             * current Location. This is done to have the current SiteKey and
                             * LocationKey preserved throughout the whole process of working with the
                             * Locations. The SiteKey and LocationKey are exchanged with the ones of
                             * the existing Location before the DataRow gets sent back to the Client!
                             */
                            ALocationRow.SiteKey = CurrentSiteKey;
                            ALocationRow.LocationKey = CurrentLocationKey;
//                          TLogging.LogAtLevel(9, "CheckReUseExistingLocation: Location " + ALocationRow.LocationKey.ToString() +
//                                ": data got replaced with data from the existing Location (" + ExistingLocationKey.ToString() + ")!");
                        }
                        else
                        {
                            throw new EOPAppException(
                                "Couldn''t find existing Similar Location with SiteKey " + ALocationRow.SiteKey.ToString() + " and LocationKey " +
                                ALocationRow.LocationKey.ToString() + '!');
                        }
                    }
                }
            }
            else
            {
//              TLogging.LogAtLevel(9, "CheckReUseExistingLocation: Location " + ALocationRow.LocationKey.ToString() +
//                  ": Location does not exist yet (or an existing Location should not be re-used) -> will get saved later.");

                /*
                 * No similar Location exists, or an existing similar Location should
                 * not be re-used: Save this Location
                 * -> will get saved later in call to SubmitChanges
                 */
            }

            return TSubmitChangesResult.scrOK;
        }
        /// <summary>
        /// Prepare the address changes. Check for the rules regarding locations
        /// </summary>
        public static TSubmitChangesResult PrepareChanges(PartnerEditTDS AInspectDS,
            Int64 APartnerKey,
            String APartnerClass,
            TDBTransaction ASubmitChangesTransaction,
            ref PartnerAddressAggregateTDS AResponseDS,
            out TVerificationResultCollection AVerificationResult)
        {
            PartnerAddressAggregateTDSSimilarLocationParametersTable ExistingLocationParametersDT;
            PartnerAddressAggregateTDSChangePromotionParametersTable ChangeLocationParametersDT;
            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AddressAddedOrChangedPromotionParametersDT;

            AVerificationResult = null;

            if (AInspectDS == null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: AInspectDS = nil!");
                return TSubmitChangesResult.scrNothingToBeSaved;
            }

            AVerificationResult = new TVerificationResultCollection();
            TLocationPK[, ] SimilarLocationReUseKeyMapping = new TLocationPK[1, 2];

            if (AInspectDS.PLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: PLocation Rows: " + AInspectDS.PLocation.Rows.Count.ToString());
            }

            if (AInspectDS.PPartnerLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: PPartnerLocation Rows: " + AInspectDS.PPartnerLocation.Rows.Count.ToString());
            }

            if (TLogging.DL >= 8)
            {
                DebugLocationsBeforeSaving(AInspectDS);
            }

            // Check if Parameter Tables are passed in
            CheckParameterTables(AResponseDS,
                out ExistingLocationParametersDT,
                out ChangeLocationParametersDT,
                out AddressAddedOrChangedPromotionParametersDT);

            if (AInspectDS.PLocation != null)
            {
                TSubmitChangesResult result = ProcessLocationChanges(
                    AInspectDS.PLocation,
                    AInspectDS.PPartnerLocation,
                    ref AResponseDS,
                    ASubmitChangesTransaction,
                    APartnerKey,
                    ref ExistingLocationParametersDT,
                    ref SimilarLocationReUseKeyMapping,
                    ref AddressAddedOrChangedPromotionParametersDT,
                    ref ChangeLocationParametersDT,
                    ref AVerificationResult);

                if (result != TSubmitChangesResult.scrOK)
                {
                    // Stop processing here, we need more information!

                    return result;
                }
            }

            if (AInspectDS.PPartnerLocation != null)
            {
                TSubmitChangesResult result = ProcessPartnerLocationChanges(
                    AInspectDS.PPartnerLocation,
                    ref AResponseDS,
                    ASubmitChangesTransaction,
                    APartnerKey,
                    APartnerClass,
                    ref SimilarLocationReUseKeyMapping,
                    ref ExistingLocationParametersDT,
                    ref AddressAddedOrChangedPromotionParametersDT,
                    ref ChangeLocationParametersDT,
                    ref AVerificationResult);

                if (result != TSubmitChangesResult.scrOK)
                {
                    // Stop processing here, we need more information!

                    return result;
                }
            }

            /*
             * Actual saving of data
             */
            if (AInspectDS.PLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: Length(SimilarLocationReUseKeyMapping): " + Convert.ToInt16(SimilarLocationReUseKeyMapping.GetLength(0)).ToString());

                if ((SimilarLocationReUseKeyMapping.GetLength(0) - 1) > 0)
                {
                    for (Int16 LocationReUseCounter = 1;
                         LocationReUseCounter <= SimilarLocationReUseKeyMapping.GetLength(0) - 1;
                         LocationReUseCounter += 1)
                    {
/* if DEBUGMODE
 *                      if (TLogging.DL >= 9)
 *                      {
 *                          TLogging.Log("LocationReUseCounter: " + LocationReUseCounter.ToString());
 *                          TLogging.Log(
 *                              "SubmitChanges: LocationReUseKeyMapping[" + LocationReUseCounter.ToString() +
 *                              ", 0].LocationKey: " +
 *                              SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString());
 *                          TLogging.Log(
 *                              "SubmitChanges: LocationReUseKeyMapping[" + LocationReUseCounter.ToString() +
 *                              ", 1].LocationKey: " +
 *                              SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].LocationKey.ToString());
 *                      }
 */
                        PLocationRow ReUsedLocationDR =
                            (PLocationRow)AInspectDS.PLocation.Rows.Find(
                                new System.Object[] { SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].SiteKey,
                                                      SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey });

                        if (ReUsedLocationDR != null)
                        {
                            // Overwrite the originally submitted Key with the one that
                            // replaces it. This is needed to have the correct Key on
                            // the Client side!
                            ReUsedLocationDR.SiteKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].SiteKey;
                            ReUsedLocationDR.LocationKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].LocationKey;

                            // Make the DataRow 'unchanged' so that it doesn't get saved in the
                            // SubmitChanges call for PLocation!
                            ReUsedLocationDR.AcceptChanges();

                            // Remember that the row should not be submitted lateron
                            // NotToBeSubmittedLocationRows.Add(ReUsedLocationDR);
                        }
                        else
                        {
                            throw new EOPAppException("ReUsedLocationDR for SiteKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter,
                                                               0].SiteKey.ToString() + " and LocationKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString() + " could not be found!");
                        }
                    }
                }
            }

            if (AInspectDS.PPartnerLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: Length(SimilarLocationReUseKeyMapping): " + Convert.ToInt16(SimilarLocationReUseKeyMapping.GetLength(0)).ToString());

                if ((SimilarLocationReUseKeyMapping.GetLength(0) - 1) > 0)
                {
                    for (Int16 LocationReUseCounter = 1;
                         LocationReUseCounter <= SimilarLocationReUseKeyMapping.GetLength(0) - 1;
                         LocationReUseCounter += 1)
                    {
//                      TLogging.LogAtLevel(9, "LocationReUseCounter: " + LocationReUseCounter.ToString());
//                      TLogging.LogAtLevel(9, "SubmitChanges: LocationReUseKeyMapping[" + LocationReUseCounter.ToString() + ", 0].LocationKey: " +
//                                SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString());
                        PPartnerLocationRow ReUsedPartnerLocationDR = (PPartnerLocationRow)AInspectDS.PPartnerLocation.Rows.Find(
                            new System.Object[] { APartnerKey, SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].SiteKey,
                                                  SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey });

                        if (ReUsedPartnerLocationDR != null)
                        {
                            // Overwrite the originally submitted Key with the one that
                            // replaces it. This is needed to have the correct Key on
                            // the Client side!
                            ReUsedPartnerLocationDR.SiteKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].SiteKey;
                            ReUsedPartnerLocationDR.LocationKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].LocationKey;
                        }
                        else
                        {
                            throw new EOPAppException("ReUsedPartnerLocationDR for SiteKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter,
                                                               0].SiteKey.ToString() + " and LocationKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString() + " could not be found!");
                        }
                    }
                }
            }

            return TSubmitChangesResult.scrOK;
        }