public List<IShippingRate> RateShipment(IShipment shipment)
        {
            _Messages.Clear();

            List<IShippingRate> result = new List<IShippingRate>();

            bool hasErrors = false;


            int serviceCode = Settings.ServiceCode;
            int packaging = Settings.Packaging;

            try
            {
                List<Shipment> optimizedPackages = this.OptimizeSingleGroup(shipment);

                if (optimizedPackages.Count > 0)
                {
                    result = RatePackages(optimizedPackages);
                }
                else
                {
                    if (this.GlobalSettings.DiagnosticsMode)
                    {
                        _Logger.LogMessage("No packages found to rate for FedEx");
                    }
                }

                
            }
            catch (Exception ex)
            {
                _Logger.LogException(ex);
                ShippingServiceMessage m = new ShippingServiceMessage();
                m.SetError("Exception", ex.Message + " | " + ex.StackTrace);
                _Messages.Add(m);
            }

            if (hasErrors)
            {
                result = new List<IShippingRate>();
            }            
            return result;
        }
        private List<IShippingRate> GetAllShippingRatesForShipment(IShipment shipment)
        {
            List<IShippingRate> rates = new List<IShippingRate>();

            bool hasErrors = false;
            
            try
            {
                List<DomesticPackage> packagesToRate = OptimizePackages(shipment);

                if (packagesToRate.Count > 0)
                {
                    rates = RatePackages(packagesToRate);
                }
                else
                {
                    if (this.GlobalSettings.DiagnosticsMode)
                    {
                        _Logger.LogMessage("No Packaged to Rate for US Postal Service: Code 795");
                    }
                }
            }

            catch (Exception ex)
            {
                _Logger.LogException(ex);
                ShippingServiceMessage m = new ShippingServiceMessage();
                m.SetError("Exception", ex.Message + " | " + ex.StackTrace);
                _Messages.Add(m);
            }

            if (hasErrors)
            {
                rates = new List<IShippingRate>();
            }
            return rates;
        }
        // Gets all available rates regardless of settings
        private List<IShippingRate> GetAllShippingRatesForShipment(IShipment shipment)
        {
            List<IShippingRate> rates = new List<IShippingRate>();

            bool hasErrors = false;
            const string UPSLIVESERVER = @"https://www.ups.com/ups.app/xml/";

            try
            {

                string sErrorMessage = "";
                string sErrorCode = "";

                string sURL = "";
                sURL = UPSLIVESERVER;
                sURL += "Rate";

                // Build XML
                string sXML = "";
                UpsSettings settings = new UpsSettings();

                settings.UserID = GlobalSettings.Username;
                settings.Password = GlobalSettings.Password;
                settings.ServerUrl = UPSLIVESERVER;
                settings.License = GlobalSettings.LicenseNumber;

                sXML = XmlTools.BuildAccessKey(settings);
                sXML += "\n";

                sXML += BuildUPSRateRequestForShipment(shipment);

                if (GlobalSettings.DiagnosticsMode)
                {
                    _Logger.LogMessage("UPS Request: " + sXML);
                    ShippingServiceMessage m = new ShippingServiceMessage();
                    m.SetDiagnostics("", "Request:" + sXML);
                    _Messages.Add(m);
                }

                string sResponse = "";
                sResponse = XmlTools.ReadHtmlPage_POST(sURL, sXML);

                if (GlobalSettings.DiagnosticsMode)
                {
                    _Logger.LogMessage("UPS Response: " + sResponse);
                    ShippingServiceMessage m = new ShippingServiceMessage();
                    m.SetDiagnostics("","Response:" + sResponse);
                    _Messages.Add(m);
                }

                XmlDocument xDoc;
                XmlNodeList NodeList;
                string sStatusCode = "-1";

                // Rated Packages will be used to return a list of suggested packages
                Collection<Package> ratedPackages = new Collection<Package>();

                try
                {
                    xDoc = new XmlDocument();
                    xDoc.LoadXml(sResponse);

                    if (xDoc.DocumentElement.Name == "RatingServiceSelectionResponse")
                    {
                        XmlNode n;
                        int i = 0;
                        XmlNode nTag;

                        NodeList = xDoc.GetElementsByTagName("RatingServiceSelectionResponse");
                        n = NodeList.Item(0);
                        for (i = 0; i <= n.ChildNodes.Count - 1; i++)
                        {
                            nTag = n.ChildNodes.Item(i);
                            switch (nTag.Name)
                            {
                                case "Response":
                                    int iRes = 0;
                                    XmlNode nRes;
                                    for (iRes = 0; iRes <= nTag.ChildNodes.Count - 1; iRes++)
                                    {
                                        nRes = nTag.ChildNodes[iRes];
                                        switch (nRes.Name)
                                        {
                                            case "ResponseStatusCode":
                                                sStatusCode = nRes.FirstChild.Value;
                                                break;
                                            case "ResponseStatusDescription":
                                                // Not Used
                                                break;
                                            case "Error":
                                                int iErr = 0;
                                                XmlNode nErr;
                                                for (iErr = 0; iErr <= nRes.ChildNodes.Count - 1; iErr++)
                                                {
                                                    nErr = nRes.ChildNodes[iErr];
                                                    switch (nErr.Name)
                                                    {
                                                        case "ErrorCode":
                                                            sErrorCode = nErr.FirstChild.Value;
                                                            break;
                                                        case "ErrorDescription":
                                                            sErrorMessage = nErr.FirstChild.Value;
                                                            break;
                                                        case "ErrorSeverity":
                                                            // Not Used
                                                            break;
                                                    }
                                                }
                                                break;

                                        }
                                    }
                                    break;
                                case "RatedShipment":

                                    int iRated = 0;
                                    XmlNode nRated;

                                    string sPostage = string.Empty;
                                    string sCurrencyCode =string.Empty;
                                    string sCode = string.Empty;
                                    string sDescription = string.Empty;

                                    for (iRated = 0; iRated <= nTag.ChildNodes.Count - 1; iRated++)
                                    {
                                        nRated = nTag.ChildNodes[iRated];
                                        switch (nRated.Name)
                                        {
                                            case "Service":
                                                int iServices = 0;
                                                XmlNode nServices;
                                                for (iServices = 0; iServices <= nRated.ChildNodes.Count - 1; iServices++)
                                                {
                                                    nServices = nRated.ChildNodes[iServices];
                                                    switch (nServices.Name)
                                                    {
                                                        case "Code":
                                                            sCode = nServices.FirstChild.Value;
                                                            sDescription = DecodeUpsServiceCode(sCode);
                                                            break;
                                                        case "Description":
                                                            sDescription = nServices.FirstChild.Value;
                                                            break;
                                                    }
                                                }
                                                break;
                                            case "TotalCharges":
                                                int iCharges = 0;
                                                XmlNode nCharges;
                                                for (iCharges = 0; iCharges <= nRated.ChildNodes.Count - 1; iCharges++)
                                                {
                                                    nCharges = nRated.ChildNodes[iCharges];
                                                    switch (nCharges.Name)
                                                    {
                                                        case "MonetaryValue":
                                                            sPostage = nCharges.FirstChild.Value;
                                                            break;
                                                        case "CurrencyCode":
                                                            sCurrencyCode = nCharges.FirstChild.Value;
                                                            break;
                                                    }
                                                }
                                                break;

                                        }
                                    }

                                    decimal dRate = -1;

                                    if (sPostage.Length > 0)
                                    {
                                        dRate = decimal.Parse(sPostage, System.Globalization.NumberStyles.Currency, System.Globalization.CultureInfo.InvariantCulture);
                                    }
                                    else
                                    {
                                        ShippingServiceMessage nop = new ShippingServiceMessage();
                                        nop.SetInfo("","No UPS Postage Found");
                                        _Messages.Add(nop);
                                        hasErrors = true;
                                    }

                                    if (dRate >= 0)
                                    {
                                        ShippingRate r =new ShippingRate();
                                        r.DisplayName = sDescription;
                                        r.EstimatedCost = dRate;
                                        r.ServiceCodes = sCode;
                                        r.ServiceId = this.Id;
                                        rates.Add(r);
                                    }

                                    if (GlobalSettings.DiagnosticsMode)
                                    {
                                        ShippingServiceMessage msg = new ShippingServiceMessage();
                                        msg.SetDiagnostics("UPS Rates Found", "StatusCode=" + sStatusCode + ",Postage=" + sPostage + ",Errors=" + sErrorMessage + ",Rate=" + dRate.ToString());
                                        _Messages.Add(msg);
                                        _Logger.LogMessage("UPS Rates Found: StatusCode=" + sStatusCode + ",Postage=" + sPostage + ",Errors=" + sErrorMessage + ",Rate=" + dRate.ToString());
                                    }

                                    break;

                            }
                        }
                    }
                    else
                    {
                        hasErrors = true;
                        sErrorMessage = "Couldn't find valid XML response from server.";
                    }
                }

                catch (Exception Exx)
                {
                    _Logger.LogException(Exx);
                    ShippingServiceMessage mex = new ShippingServiceMessage();
                    mex.SetError("Exception", Exx.Message + " | " + Exx.Source);
                    _Messages.Add(mex);
                    return rates;
                }

                if (sStatusCode != "1")
                {
                    hasErrors = true;
                }

            }

            catch (Exception ex)
            {
                _Logger.LogException(ex);
                ShippingServiceMessage m = new ShippingServiceMessage();
                m.SetError("Exception", ex.Message + " | " + ex.StackTrace);
                _Messages.Add(m);
            }

            if (hasErrors)
            {
                rates = new List<IShippingRate>();
            }
            return rates;
        }