/// <summary>
        /// The to fixed rate ship method.
        /// </summary>
        /// <param name="rateTable">
        /// The rate table.
        /// </param>
        /// <param name="destination">
        /// The destination.
        /// </param>
        /// <returns>
        /// The <see cref="IFixedRateShippingGatewayMethod"/>.
        /// </returns>
        internal static IFixedRateShippingGatewayMethod ToFixedRateShipMethod(this ShipFixedRateTableDisplay rateTable, IFixedRateShippingGatewayMethod destination)
        {
            // Rate table
            var existingRows = rateTable.Rows.Where(x => !x.Key.Equals(Guid.Empty)).ToArray();

            foreach (var mapRow in existingRows)
            {
                var row = destination.RateTable.Rows.FirstOrDefault(x => x.Key == mapRow.Key);
                if (row != null)
                {
                    row.Rate = mapRow.Rate;
                }
            }

            // remove existing rows that previously existed but were deleted in the UI
            var removers =
                destination.RateTable.Rows.Where(
                    row =>
                    !row.Key.Equals(Guid.Empty) &&
                    existingRows.All(x => x.Key != row.Key && !x.Key.Equals(Guid.Empty)));

            foreach (var remove in removers)
            {
                destination.RateTable.DeleteRow(remove);
            }

            // add any new rows
            foreach (var newRow in rateTable.Rows.Where(x => x.Key == Guid.Empty))
            {
                destination.RateTable.AddRow(newRow.RangeLow, newRow.RangeHigh, newRow.Rate);
            }

            return(destination);
        }
        /// <summary>
        /// Maps changes made in the <see cref="ShipFixedRateTableDisplay"/> to the <see cref="IShippingFixedRateTable"/>
        /// </summary>
        /// <param name="shipFixedRateTableDisplay">The <see cref="ShipFixedRateTableDisplay"/> to map</param>
        /// <param name="destination">The <see cref="IShippingFixedRateTable"/> to have changes mapped to</param>
        /// <returns>The updated <see cref="IShippingFixedRateTable"/></returns>
        /// <remarks>
        ///
        /// Note: after calling this mapping, the changes are still not persisted to the database as the .Save() method is not called.
        ///
        /// * For testing you will have to use the static .Save(IGatewayProviderService ..., as MerchelloContext.Current will likely be null
        ///
        /// </remarks>
        internal static IShippingFixedRateTable ToShipRateTable(this ShipFixedRateTableDisplay shipFixedRateTableDisplay, IShippingFixedRateTable destination)
        {
            // determine if any rows were deleted
            var missingRows =
                destination.Rows.Where(
                    persisted => !shipFixedRateTableDisplay.Rows.Select(display => display.Key).Where(x => x != Guid.Empty).Contains(persisted.Key));

            foreach (var missing in missingRows)
            {
                destination.DeleteRow(missing);
            }

            foreach (var shipRateTierDisplay in shipFixedRateTableDisplay.Rows)
            {
                // try to find the matching row
                var destinationTier = destination.Rows.FirstOrDefault(x => x.Key == shipRateTierDisplay.Key);

                if (destinationTier != null)
                {
                    // update the tier information : note we can only update the Rate here!
                    // We need to remove the text boxes for the RangeLow and RangeHigh on any existing FixedRateTable
                    destinationTier.Rate = shipRateTierDisplay.Rate;
                }
                else
                {
                    // this should be implemented in V1
                    destination.AddRow(shipRateTierDisplay.RangeLow, shipRateTierDisplay.RangeHigh, shipRateTierDisplay.Rate);
                }

                //IShipRateTier destinationShipRateTier;

                //var matchingItems = destination.Rows.Where(x => x.Key == shipRateTierDisplay.Key).ToArray();
                //if (matchingItems.Any())
                //{
                //    var existingshipRateTier = matchingItems.First();
                //    if (existingshipRateTier != null)
                //    {
                //        destinationShipRateTier = existingshipRateTier;

                //        destinationShipRateTier = shipRateTierDisplay.ToShipRateTier(destinationShipRateTier);
                //    }
                //}
                //else
                //{
                //    // Case if one was created in the back-office.  Not planned for v1
                //    destination.AddRow(shipRateTierDisplay.RangeLow, shipRateTierDisplay.RangeHigh, shipRateTierDisplay.Rate);
                //}
            }

            return(destination);
        }