/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/

package org.apache.ofbiz.shipment.thirdparty.usps;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;

import javax.xml.transform.TransformerException;

import org.apache.commons.lang.StringUtils;
import org.apache.ofbiz.base.util.Base64;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.HttpClient;
import org.apache.ofbiz.base.util.HttpClientException;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.common.uom.UomWorker;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.ofbiz.entity.util.EntityUtilProperties;
import org.apache.ofbiz.party.contact.ContactMechWorker;
import org.apache.ofbiz.product.product.ProductWorker;
import org.apache.ofbiz.product.store.ProductStoreWorker;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ModelService;
import org.apache.ofbiz.service.ServiceUtil;
import org.apache.ofbiz.shipment.shipment.ShipmentServices;
import org.apache.ofbiz.shipment.shipment.ShipmentWorker;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * USPS Webtools API Services
 */
public class UspsServices {

    public final static String module = UspsServices.class.getName();
    public final static String resourceError = "ProductUiLabels";

    private static List<String> domesticCountries = new LinkedList<String>();
    // Countries treated as domestic for rate enquiries
    static {
        domesticCountries.add("USA");
        domesticCountries.add("ASM");
        domesticCountries.add("GU");
        domesticCountries = Collections.unmodifiableList(domesticCountries);
    }

    public static Map<String, Object> uspsRateInquire(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        Locale locale = (Locale) context.get("locale");
        
        // check for 0 weight
        BigDecimal shippableWeight = (BigDecimal) context.get("shippableWeight");
        if (shippableWeight.compareTo(BigDecimal.ZERO) == 0) {
            // TODO: should we return an error, or $0.00 ?
            return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsShippableWeightMustGreaterThanZero", locale));
        }

        // get the origination ZIP
        String originationZip = null;
        GenericValue productStore = ProductStoreWorker.getProductStore(((String) context.get("productStoreId")), delegator);
        if (productStore != null && productStore.get("inventoryFacilityId") != null) {
            GenericValue facilityContactMech = ContactMechWorker.getFacilityContactMechByPurpose(delegator, productStore.getString("inventoryFacilityId"), UtilMisc.toList("SHIP_ORIG_LOCATION", "PRIMARY_LOCATION"));
            if (facilityContactMech != null) {
                try {
                    GenericValue shipFromAddress = EntityQuery.use(delegator).from("PostalAddress").where("contactMechId", facilityContactMech.getString("contactMechId")).queryOne();
                    if (shipFromAddress != null) {
                        originationZip = shipFromAddress.getString("postalCode");
                    }
                } catch (GenericEntityException e) {
                    Debug.logError(e, module);
                }
            }
        }
        if (UtilValidate.isEmpty(originationZip)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsUnableDetermineOriginationZip", locale));
        }

        // get the destination ZIP
        String destinationZip = null;
        String shippingContactMechId = (String) context.get("shippingContactMechId");
        if (UtilValidate.isNotEmpty(shippingContactMechId)) {
            try {
                GenericValue shipToAddress = EntityQuery.use(delegator).from("PostalAddress").where("contactMechId", shippingContactMechId).queryOne();
                if (shipToAddress != null) {
                    if (!domesticCountries.contains(shipToAddress.getString("countryGeoId"))) {
                        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                                "FacilityShipmentUspsRateInquiryOnlyInUsDestinations", locale));
                    }
                    destinationZip = shipToAddress.getString("postalCode");
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, module);
            }
        }
        if (UtilValidate.isEmpty(destinationZip)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsUnableDetermineDestinationZip", locale));
        }

        // get the service code
        String serviceCode = null;
        try {
            GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod")
                    .where("shipmentMethodTypeId", (String) context.get("shipmentMethodTypeId"), "partyId", (String) context.get("carrierPartyId"), "roleTypeId", (String) context.get("carrierRoleTypeId"))
                    .queryOne();
            if (carrierShipmentMethod != null) {
                serviceCode = carrierShipmentMethod.getString("carrierServiceCode").toUpperCase();
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
        }
        if (UtilValidate.isEmpty(serviceCode)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsUnableDetermineServiceCode", locale));
        }

        // create the request document
        Document requestDocument = createUspsRequestDocument("RateV2Request", true, delegator, shipmentGatewayConfigId, resource);

        // TODO: 70 lb max is valid for Express, Priority and Parcel only - handle other methods
        BigDecimal maxWeight = new BigDecimal("70");
        String maxWeightStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "maxEstimateWeight", 
                resource, "shipment.usps.max.estimate.weight", "70");
        try {
            maxWeight = new BigDecimal(maxWeightStr);
        } catch (NumberFormatException e) {
            Debug.logWarning("Error parsing max estimate weight string [" + maxWeightStr + "], using default instead", module);
            maxWeight = new BigDecimal("70");
        }

        List<Map<String, Object>> shippableItemInfo = UtilGenerics.checkList(context.get("shippableItemInfo"));
        List<Map<String, BigDecimal>> packages = ShipmentWorker.getPackageSplit(dctx, shippableItemInfo, maxWeight);
        boolean isOnePackage = packages.size() == 1; // use shippableWeight if there's only one package
        // TODO: Up to 25 packages can be included per request - handle more than 25
        for (ListIterator<Map<String, BigDecimal>> li = packages.listIterator(); li.hasNext();) {
            Map<String, BigDecimal> packageMap = li.next();

            BigDecimal packageWeight = isOnePackage ? shippableWeight : ShipmentWorker.calcPackageWeight(dctx, packageMap, shippableItemInfo, BigDecimal.ZERO);
            if (packageWeight.compareTo(BigDecimal.ZERO) == 0) {
                continue;
            }

            Element packageElement = UtilXml.addChildElement(requestDocument.getDocumentElement(), "Package", requestDocument);
            packageElement.setAttribute("ID", String.valueOf(li.nextIndex() - 1)); // use zero-based index (see examples)

            UtilXml.addChildElementValue(packageElement, "Service", serviceCode, requestDocument);
            UtilXml.addChildElementValue(packageElement, "ZipOrigination", StringUtils.substring(originationZip, 0, 5), requestDocument);
            UtilXml.addChildElementValue(packageElement, "ZipDestination", StringUtils.substring(destinationZip, 0, 5), requestDocument);

            BigDecimal weightPounds = packageWeight.setScale(0, BigDecimal.ROUND_FLOOR);
            // for Parcel post, the weight must be at least 1 lb
            if ("PARCEL".equals(serviceCode.toUpperCase()) && (weightPounds.compareTo(BigDecimal.ONE) < 0)) {
                weightPounds = BigDecimal.ONE;
                packageWeight = BigDecimal.ZERO;
            }
            // (packageWeight % 1) * 16 (Rounded up to 0 dp)
            BigDecimal weightOunces = packageWeight.remainder(BigDecimal.ONE).multiply(new BigDecimal("16")).setScale(0, BigDecimal.ROUND_CEILING);
            
            UtilXml.addChildElementValue(packageElement, "Pounds", weightPounds.toPlainString(), requestDocument);
            UtilXml.addChildElementValue(packageElement, "Ounces", weightOunces.toPlainString(), requestDocument);

            // TODO: handle other container types, package sizes, and machinable packages
            // IMPORTANT: Express or Priority Mail will fail if you supply a Container tag: you will get a message like
            // Invalid container type. Valid container types for Priority Mail are Flat Rate Envelope and Flat Rate Box.
            /* This is an official response from the United States Postal Service:
            The <Container> tag is used to specify the flat rate mailing options, or the type of large or oversized package being mailed.
            If you are wanting to get regular Express Mail rates, leave the <Container> tag empty, or do not include it in the request at all.
             */
            if ("Parcel".equalsIgnoreCase(serviceCode)) {
                UtilXml.addChildElementValue(packageElement, "Container", "None", requestDocument);
            }
            UtilXml.addChildElementValue(packageElement, "Size", "REGULAR", requestDocument);
            UtilXml.addChildElementValue(packageElement, "Machinable", "false", requestDocument);
        }

        // send the request
        Document responseDocument = null;
        try {
            responseDocument = sendUspsRequest("RateV2", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
        } catch (UspsRequestException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateDomesticSendingError", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        if (responseDocument == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentRateNotAvailable", locale));
        }

        List<? extends Element> rates = UtilXml.childElementList(responseDocument.getDocumentElement(), "Package");
        if (UtilValidate.isEmpty(rates)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentRateNotAvailable", locale));
        }

        BigDecimal estimateAmount = BigDecimal.ZERO;
        for (Element packageElement: rates) {
            try {
                Element postageElement = UtilXml.firstChildElement(packageElement, "Postage");
                BigDecimal packageAmount = new BigDecimal(UtilXml.childElementValue(postageElement, "Rate"));
                estimateAmount = estimateAmount.add(packageAmount);
            } catch (NumberFormatException e) {
                Debug.logInfo(e, module);
            }
        }

        Map<String, Object> result = ServiceUtil.returnSuccess();
        result.put("shippingEstimateAmount", estimateAmount);
        return result;
    }

    /*
     * USPS International Service Codes
     * 1 - Express Mail International
     * 2 - Priority Mail International
     * 4 - Global Express Guaranteed (Document and Non-document)
     * 5 - Global Express Guaranteed Document used
     * 6 - Global Express Guaranteed Non-Document Rectangular shape
     * 7 - Global Express Guaranteed Non-Document Non-Rectangular
     * 8 - Priority Mail Flat Rate Envelope
     * 9 - Priority Mail Flat Rate Box
     * 10 - Express Mail International Flat Rate Envelope
     * 11 - Priority Mail Large Flat Rate Box
     * 12 - Global Express Guaranteed Envelope
     * 13 - First Class Mail International Letters
     * 14 - First Class Mail International Flats
     * 15 - First Class Mail International Parcels
     * 16 - Priority Mail Small Flat Rate Box
     * 21 - PostCards
     */
    public static Map<String, Object> uspsInternationalRateInquire(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        Locale locale = (Locale) context.get("locale");

        // check for 0 weight
        BigDecimal shippableWeight = (BigDecimal) context.get("shippableWeight");
        if (shippableWeight.compareTo(BigDecimal.ZERO) == 0) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsShippableWeightMustGreaterThanZero", locale));
        }

        // get the destination country
        String destinationCountry = null;
        String shippingContactMechId = (String) context.get("shippingContactMechId");
        if (UtilValidate.isNotEmpty(shippingContactMechId)) {
            try {
                GenericValue shipToAddress = EntityQuery.use(delegator).from("PostalAddress").where("contactMechId", shippingContactMechId).queryOne();
                if (domesticCountries.contains(shipToAddress.get("countryGeoId"))) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsRateInternationCannotBeUsedForUsDestinations", locale));
                }
                if (shipToAddress != null && UtilValidate.isNotEmpty(shipToAddress.getString("countryGeoId"))) {
                    GenericValue countryGeo = shipToAddress.getRelatedOne("CountryGeo", false);
                    // TODO: Test against all country geoNames against what USPS expects
                    destinationCountry = countryGeo.getString("geoName");
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, module);
            }
        }
        if (UtilValidate.isEmpty(destinationCountry)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsUnableDetermineDestinationCountry", locale));
        }

        // get the service code
        String serviceCode = null;
        try {
            GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod")
                    .where("shipmentMethodTypeId", (String) context.get("shipmentMethodTypeId"), "partyId", (String) context.get("carrierPartyId"), "roleTypeId", (String) context.get("carrierRoleTypeId"))
                    .queryOne();
            if (carrierShipmentMethod != null) {
                serviceCode = carrierShipmentMethod.getString("carrierServiceCode");
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
        }
        if (UtilValidate.isEmpty(serviceCode)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsUnableDetermineServiceCode", locale));
        }

        BigDecimal maxWeight = new BigDecimal("70");
        String maxWeightStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "maxEstimateWeight", 
                resource, "shipment.usps.max.estimate.weight", "70");
        try {
            maxWeight = new BigDecimal(maxWeightStr);
        } catch (NumberFormatException e) {
            Debug.logWarning("Error parsing max estimate weight string [" + maxWeightStr + "], using default instead", module);
            maxWeight = new BigDecimal("70");
        }

        List<Map<String, Object>> shippableItemInfo = UtilGenerics.checkList(context.get("shippableItemInfo"));
        List<Map<String, BigDecimal>> packages = ShipmentWorker.getPackageSplit(dctx, shippableItemInfo, maxWeight);
        boolean isOnePackage = packages.size() == 1; // use shippableWeight if there's only one package

        // create the request document
        Document requestDocument = createUspsRequestDocument("IntlRateRequest", false, delegator, shipmentGatewayConfigId, resource);

        // TODO: Up to 25 packages can be included per request - handle more than 25
        for (ListIterator<Map<String, BigDecimal>> li = packages.listIterator(); li.hasNext();) {
            Map<String, BigDecimal> packageMap = li.next();

            Element packageElement = UtilXml.addChildElement(requestDocument.getDocumentElement(), "Package", requestDocument);
            packageElement.setAttribute("ID", String.valueOf(li.nextIndex() - 1)); // use zero-based index (see examples)

            BigDecimal packageWeight = isOnePackage ? shippableWeight : ShipmentWorker.calcPackageWeight(dctx, packageMap, shippableItemInfo, BigDecimal.ZERO);
            if (packageWeight.compareTo(BigDecimal.ZERO) == 0) {
                continue;
            }
            Integer[] weightPoundsOunces = convertPoundsToPoundsOunces(packageWeight);
            // for Parcel post, the weight must be at least 1 lb
            if ("PARCEL".equals(serviceCode.toUpperCase()) && (weightPoundsOunces[0] < 1)) {
                weightPoundsOunces[0] = 1;
                weightPoundsOunces[1] = 0;
            }
            UtilXml.addChildElementValue(packageElement, "Pounds", weightPoundsOunces[0].toString(), requestDocument);
            UtilXml.addChildElementValue(packageElement, "Ounces", weightPoundsOunces[1].toString(), requestDocument);

            UtilXml.addChildElementValue(packageElement, "Machinable", "False", requestDocument);
            UtilXml.addChildElementValue(packageElement, "MailType", "Package", requestDocument);

            // TODO: Add package value so that an insurance fee can be returned

            UtilXml.addChildElementValue(packageElement, "Country", destinationCountry, requestDocument);
        }

        // send the request
        Document responseDocument = null;
        try {
            responseDocument = sendUspsRequest("IntlRate", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
        } catch (UspsRequestException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateInternationalSendingError", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        if (responseDocument == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentRateNotAvailable", locale));
        }

        List<? extends Element> packageElements = UtilXml.childElementList(responseDocument.getDocumentElement(), "Package");
        if (UtilValidate.isEmpty(packageElements)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentRateNotAvailable", locale));
        }

        BigDecimal estimateAmount = BigDecimal.ZERO;
        for (Element packageElement: packageElements) {
            Element errorElement = UtilXml.firstChildElement(packageElement, "Error");
            if (errorElement != null) {
                String errorDescription = UtilXml.childElementValue(errorElement, "Description");
                Debug.logInfo("USPS International Rate Calculation returned a package error: " + errorDescription, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRateNotAvailable", locale));
            }
            List<? extends Element> serviceElements = UtilXml.childElementList(packageElement, "Service");
            for (Element serviceElement : serviceElements) {
                String respServiceCode = serviceElement.getAttribute("ID");
                if (!serviceCode.equalsIgnoreCase(respServiceCode)) {
                    continue;
                }
                try {
                    BigDecimal packageAmount = new BigDecimal(UtilXml.childElementValue(serviceElement, "Postage"));
                    estimateAmount = estimateAmount.add(packageAmount);
                } catch (NumberFormatException e) {
                    Debug.logInfo("USPS International Rate Calculation returned an unparsable postage amount: " + UtilXml.childElementValue(serviceElement, "Postage"), module);
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentRateNotAvailable", locale));
                }
            }
        }

        Map<String, Object> result = ServiceUtil.returnSuccess();
        result.put("shippingEstimateAmount", estimateAmount);
        return result;
    }

    // lifted from UpsServices with no changes - 2004.09.06 JFE
    /*

    Track/Confirm Samples: (API=TrackV2)

    Request:
    <TrackRequest USERID="xxxxxxxx" PASSWORD="xxxxxxxx">
        <TrackID ID="EJ958083578US"></TrackID>
    </TrackRequest>

    Response:
    <TrackResponse>
        <TrackInfo ID="EJ958083578US">
            <TrackSummary>Your item was delivered at 8:10 am on June 1 in Wilmington DE 19801.</TrackSummary>
            <TrackDetail>May 30 11:07 am NOTICE LEFT WILMINGTON DE 19801.</TrackDetail>
            <TrackDetail>May 30 10:08 am ARRIVAL AT UNIT WILMINGTON DE 19850.</TrackDetail>
            <TrackDetail>May 29 9:55 am ACCEPT OR PICKUP EDGEWATER NJ 07020.</TrackDetail>
        </TrackInfo>
    </TrackResponse>

    */

    public static Map<String, Object> uspsTrackConfirm(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        Locale locale = (Locale) context.get("locale");

        Document requestDocument = createUspsRequestDocument("TrackRequest", true, delegator, shipmentGatewayConfigId, resource);

        Element trackingElement = UtilXml.addChildElement(requestDocument.getDocumentElement(), "TrackID", requestDocument);
        trackingElement.setAttribute("ID", (String) context.get("trackingId"));

        Document responseDocument = null;
        try {
            responseDocument = sendUspsRequest("TrackV2", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
        } catch (UspsRequestException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsTrackingSendingError", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        Element trackInfoElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "TrackInfo");
        if (trackInfoElement == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsTrackingIncompleteResponse", locale));
        }

        Map<String, Object> result = ServiceUtil.returnSuccess();

        result.put("trackingSummary", UtilXml.childElementValue(trackInfoElement, "TrackSummary"));

        List<? extends Element> detailElementList = UtilXml.childElementList(trackInfoElement, "TrackDetail");
        if (UtilValidate.isNotEmpty(detailElementList)) {
            List<String> trackingDetailList = new LinkedList<String>();
            for (Element detailElement: detailElementList) {
                trackingDetailList.add(UtilXml.elementValue(detailElement));
            }
            result.put("trackingDetailList", trackingDetailList);
        }

        return result;
    }

    /*

    Address Standardization Samples: (API=Verify)

    Request:
    <AddressValidateRequest USERID="xxxxxxx" PASSWORD="xxxxxxx">
        <Address ID="0">
            <Address1></Address1>
            <Address2>6406 Ivy Lane</Address2>
            <City>Greenbelt</City>
            <State>MD</State>
            <Zip5></Zip5>
            <Zip4></Zip4>
        </Address>
    </AddressValidateRequest>

    Response:
    <AddressValidateResponse>
        <Address ID="0">
            <Address2>6406 IVY LN</Address2>
            <City>GREENBELT</City>
            <State>MD</State>
            <Zip5>20770</Zip5>
            <Zip4>1440</Zip4>
        </Address>
    </AddressValidateResponse>

    Note:
        The service parameters address1 and addess2 follow the OFBiz naming convention,
        and are converted to USPS conventions internally
        (OFBiz address1 = USPS address2, OFBiz address2 = USPS address1)

    */

    public static Map<String, Object> uspsAddressValidation(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        String state = (String) context.get("state");
        String city = (String) context.get("city");
        String zip5 = (String) context.get("zip5");
        Locale locale = (Locale) context.get("locale");
        if ((UtilValidate.isEmpty(state) && UtilValidate.isEmpty(city) && UtilValidate.isEmpty(zip5)) ||    // No state, city or zip5
             (UtilValidate.isEmpty(zip5) && (UtilValidate.isEmpty(state) || UtilValidate.isEmpty(city)))) {  // Both state and city are required if no zip5
            Debug.logError("USPS address validation requires either zip5 or city and state",  module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsAddressValidationStateAndCityOrZipRqd", locale));
        }

        Document requestDocument = createUspsRequestDocument("AddressValidateRequest", true, delegator, shipmentGatewayConfigId, resource);

        Element addressElement = UtilXml.addChildElement(requestDocument.getDocumentElement(), "Address", requestDocument);
        addressElement.setAttribute("ID", "0");

        // 38 chars max
        UtilXml.addChildElementValue(addressElement, "FirmName", (String) context.get("firmName"), requestDocument);
        // 38 chars max
        UtilXml.addChildElementValue(addressElement, "Address1", (String) context.get("address2"), requestDocument);
        // 38 chars max
        UtilXml.addChildElementValue(addressElement, "Address2", (String) context.get("address1"), requestDocument);
        // 15 chars max
        UtilXml.addChildElementValue(addressElement, "City", (String) context.get("city"), requestDocument);

        UtilXml.addChildElementValue(addressElement, "State", (String) context.get("state"), requestDocument);
        UtilXml.addChildElementValue(addressElement, "Zip5", (String) context.get("zip5"), requestDocument);
        UtilXml.addChildElementValue(addressElement, "Zip4", (String) context.get("zip4"), requestDocument);

        Document responseDocument = null;
        try {
            responseDocument = sendUspsRequest("Verify", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
        } catch (UspsRequestException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsAddressValidationSendingError", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        Element respAddressElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "Address");
        if (respAddressElement == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsAddressValidationIncompleteResponse", locale));
        }

        Element respErrorElement = UtilXml.firstChildElement(respAddressElement, "Error");
        if (respErrorElement != null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsAddressValidationIncompleteResponse", 
                    UtilMisc.toMap("errorString", UtilXml.childElementValue(respErrorElement, "Description")), locale));
        }

        Map<String, Object> result = ServiceUtil.returnSuccess();

        // Note: a FirmName element is not returned if empty
        String firmName = UtilXml.childElementValue(respAddressElement, "FirmName");
        if (UtilValidate.isNotEmpty(firmName)) {
            result.put("firmName", firmName);
        }

        // Note: an Address1 element is not returned if empty
        String address1 = UtilXml.childElementValue(respAddressElement, "Address1");
        if (UtilValidate.isNotEmpty(address1)) {
            result.put("address2", address1);
        }

        result.put("address1", UtilXml.childElementValue(respAddressElement, "Address2"));
        result.put("city", UtilXml.childElementValue(respAddressElement, "City"));
        result.put("state", UtilXml.childElementValue(respAddressElement, "State"));
        result.put("zip5", UtilXml.childElementValue(respAddressElement, "Zip5"));
        result.put("zip4", UtilXml.childElementValue(respAddressElement, "Zip4"));
        Element returnTextElement = UtilXml.firstChildElement(respAddressElement, "ReturnText");
        if (returnTextElement != null) {
            result.put("returnText", UtilXml.elementValue(returnTextElement));
        }
        return result;
    }

    /*

    City/State Lookup Samples: (API=CityStateLookup)

    Request:
    <CityStateLookupRequest USERID="xxxxxxx" PASSWORD="xxxxxxx">
        <ZipCode ID="0">
            <Zip5>90210</Zip5>
        </ZipCode>
    </CityStateLookupRequest>

    Response:
    <CityStateLookupResponse>
        <ZipCode ID="0">
            <Zip5>90210</Zip5>
            <City>BEVERLY HILLS</City>
            <State>CA</State>
        </ZipCode>
    </CityStateLookupResponse>

    */

    public static Map<String, Object> uspsCityStateLookup(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        Locale locale = (Locale) context.get("locale");

        Document requestDocument = createUspsRequestDocument("CityStateLookupRequest", true, delegator, shipmentGatewayConfigId, resource);

        Element zipCodeElement = UtilXml.addChildElement(requestDocument.getDocumentElement(), "ZipCode", requestDocument);
        zipCodeElement.setAttribute("ID", "0");

        String zipCode = ((String) context.get("zip5")).trim(); // trim leading/trailing spaces

        // only the first 5 digits are used, the rest are ignored
        UtilXml.addChildElementValue(zipCodeElement, "Zip5", zipCode, requestDocument);

        Document responseDocument = null;
        try {
            responseDocument = sendUspsRequest("CityStateLookup", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
        } catch (UspsRequestException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsCityStateLookupSendingError", 
                    UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        Element respAddressElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "ZipCode");
        if (respAddressElement == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsCityStateLookupIncompleteResponse", locale));
        }

        Element respErrorElement = UtilXml.firstChildElement(respAddressElement, "Error");
        if (respErrorElement != null) {
            return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsCityStateLookupResponseError", 
                    UtilMisc.toMap("errorString", UtilXml.childElementValue(respErrorElement, "Description")), locale));
        }

        Map<String, Object> result = ServiceUtil.returnSuccess();

        String city = UtilXml.childElementValue(respAddressElement, "City");
        if (UtilValidate.isEmpty(city)) {
            return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsCityStateLookupIncompleteCityElement", locale));
        }
        result.put("city", city);

        String state = UtilXml.childElementValue(respAddressElement, "State");
        if (UtilValidate.isEmpty(state)) {
            return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsCityStateLookupIncompleteStateElement", locale));
        }
        result.put("state", state);

        return result;
    }

    /*

    Service Standards Samples:

    Priority Mail: (API=PriorityMail)

        Request:
        <PriorityMailRequest USERID="xxxxxxx" PASSWORD="xxxxxxx">
            <OriginZip>4</OriginZip>
            <DestinationZip>4</DestinationZip>
        </PriorityMailRequest>

        Response:
        <PriorityMailResponse>
            <OriginZip>4</OriginZip>
            <DestinationZip>4</DestinationZip>
            <Days>1</Days>
        </PriorityMailResponse>

    Package Services: (API=StandardB)

        Request:
        <StandardBRequest USERID="xxxxxxx" PASSWORD="xxxxxxx">
            <OriginZip>4</OriginZip>
            <DestinationZip>4</DestinationZip>
        </StandardBRequest>

        Response:
        <StandardBResponse>
            <OriginZip>4</OriginZip>
            <DestinationZip>4</DestinationZip>
            <Days>2</Days>
        </StandardBResponse>

    Note:
        When submitting ZIP codes, only the first 3 digits are used.
        If a 1- or 2-digit ZIP code is entered, leading zeros are implied.
        If a 4- or 5-digit ZIP code is entered, the last digits  will be ignored.

    */

    public static Map<String, Object> uspsPriorityMailStandard(DispatchContext dctx, Map<String, ? extends Object> context) {
        Map<String, Object> subContext = UtilMisc.makeMapWritable(context);
        subContext.put("serviceType", "PriorityMail");
        return uspsServiceStandards(dctx, subContext);
    }

    public static Map<String, Object> uspsPackageServicesStandard(DispatchContext dctx, Map<String, ? extends Object> context) {
        Map<String, Object> subContext = UtilMisc.makeMapWritable(context);
        subContext.put("serviceType", "StandardB");
        return uspsServiceStandards(dctx, subContext);
    }

    private static Map<String, Object> uspsServiceStandards(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        String type = (String) context.get("serviceType");
        Locale locale = (Locale) context.get("locale");
        if (!type.matches("PriorityMail|StandardB")) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsUnsupporteServiceType", 
                    UtilMisc.toMap("serviceType", type), locale));
        }

        Document requestDocument = createUspsRequestDocument(type + "Request", true, delegator, shipmentGatewayConfigId, resource);

        UtilXml.addChildElementValue(requestDocument.getDocumentElement(), "OriginZip",
                (String) context.get("originZip"), requestDocument);
        UtilXml.addChildElementValue(requestDocument.getDocumentElement(), "DestinationZip",
                (String) context.get("destinationZip"), requestDocument);

        Document responseDocument = null;
        try {
            responseDocument = sendUspsRequest(type, requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
        } catch (UspsRequestException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsServiceStandardSendingError", 
                    UtilMisc.toMap("serviceType", type, "errorString", e.getMessage()), locale));
        }

        Map<String, Object> result = ServiceUtil.returnSuccess();

        String days = UtilXml.childElementValue(responseDocument.getDocumentElement(), "Days");
        if (UtilValidate.isEmpty(days)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsServiceStandardResponseIncompleteDaysElement", 
                    UtilMisc.toMap("serviceType", type), locale));
        }
        result.put("days", days);

        return result;
    }



    /*

    Domestic Rate Calculator Samples: (API=Rate)

    Request:
    <RateRequest USERID="xxxxxx" PASSWORD="xxxxxxx">
        <Package ID="0">
            <Service>Priority</Service>
            <ZipOrigination>20770</ZipOrigination>
            <ZipDestination>09021</ZipDestination>
            <Pounds>5</Pounds>
            <Ounces>1</Ounces>
            <Container>None</Container>
            <Size>Regular</Size>
            <Machinable>False</Machinable>
        </Package>
    </RateRequest>

    Response:
    <RateResponse>
        <Package ID="0">
            <Service>Priority</Service>
            <ZipOrigination>20770</ZipOrigination>
            <ZipDestination>09021</ZipDestination>
            <Pounds>5</Pounds>
            <Ounces>1</Ounces>
            <Container>None</Container>
            <Size>REGULAR</Size>
            <Machinable>FALSE</Machinable>
            <Zone>3</Zone>
            <Postage>7.90</Postage>
            <RestrictionCodes>B-B1-C-D-U</RestrictionCodes>
            <RestrictionDescription>
            B. Form 2976-A is required for all mail weighing 16 ounces or more, with exceptions noted below.
            In addition, mailers must properly complete required customs documentation when mailing any potentially
            dutiable mail addressed to an APO or FPO regardless of weight. B1. Form 2976 or 2976-A is required.
            Articles are liable for customs duty and/or purchase tax unless they are bona fide gifts intended for
            use by military personnel or their dependents. C. Cigarettes and other tobacco products are prohibited.
            D. Coffee is prohibited. U. Parcels must weigh less than 16 ounces when addressed to Box R.
            </RestrictionDescription>
        </Package>
    </RateResponse>

    */

    public static Map<String, Object> uspsDomesticRate(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        Locale locale = (Locale) context.get("locale");
 
        Document requestDocument = createUspsRequestDocument("RateRequest", true, delegator, shipmentGatewayConfigId, resource);

        Element packageElement = UtilXml.addChildElement(requestDocument.getDocumentElement(), "Package", requestDocument);
        packageElement.setAttribute("ID", "0");

        UtilXml.addChildElementValue(packageElement, "Service", (String) context.get("service"), requestDocument);
        UtilXml.addChildElementValue(packageElement, "ZipOrigination", (String) context.get("originZip"), requestDocument);
        UtilXml.addChildElementValue(packageElement, "ZipDestination", (String) context.get("destinationZip"), requestDocument);
        UtilXml.addChildElementValue(packageElement, "Pounds", (String) context.get("pounds"), requestDocument);
        UtilXml.addChildElementValue(packageElement, "Ounces", (String) context.get("ounces"), requestDocument);

        String container = (String) context.get("container");
        if (UtilValidate.isEmpty(container)) {
            container = "None";
        }
        UtilXml.addChildElementValue(packageElement, "Container", container, requestDocument);

        String size = (String) context.get("size");
        if (UtilValidate.isEmpty(size)) {
            size = "Regular";
        }
        UtilXml.addChildElementValue(packageElement, "Size", size, requestDocument);

        String machinable = (String) context.get("machinable");
        if (UtilValidate.isEmpty(machinable)) {
            machinable = "False";
        }
        UtilXml.addChildElementValue(packageElement, "Machinable", machinable, requestDocument);

        Document responseDocument = null;
        try {
            responseDocument = sendUspsRequest("Rate", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
        } catch (UspsRequestException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateDomesticSendingError", 
                    UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        Element respPackageElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "Package");
        if (respPackageElement == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateDomesticResponseIncompleteElementPackage", locale));
        }

        Element respErrorElement = UtilXml.firstChildElement(respPackageElement, "Error");
        if (respErrorElement != null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateDomesticResponseError", 
                    UtilMisc.toMap("errorString", UtilXml.childElementValue(respErrorElement, "Description")), locale));
        }

        Map<String, Object> result = ServiceUtil.returnSuccess();

        String zone = UtilXml.childElementValue(respPackageElement, "Zone");
        if (UtilValidate.isEmpty(zone)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateDomesticResponseIncompleteElementZone", locale));
        }
        result.put("zone", zone);

        String postage = UtilXml.childElementValue(respPackageElement, "Postage");
        if (UtilValidate.isEmpty(postage)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateDomesticResponseIncompleteElementPostage", locale));
        }
        result.put("postage", postage);

        String restrictionCodes = UtilXml.childElementValue(respPackageElement, "RestrictionCodes");
        if (UtilValidate.isNotEmpty(restrictionCodes)) {
            result.put("restrictionCodes", restrictionCodes);
        }

        String restrictionDesc = UtilXml.childElementValue(respPackageElement, "RestrictionDescription");
        if (UtilValidate.isNotEmpty(restrictionCodes)) {
            result.put("restrictionDesc", restrictionDesc);
        }

        return result;
    }

    // Warning: I don't think the following 2 services were completed or fully tested - 2004.09.06 JFE

    /* --- ShipmentRouteSegment services --------------------------------------------------------------------------- */

    public static Map<String, Object> uspsUpdateShipmentRateInfo(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        LocalDispatcher dispatcher = dctx.getDispatcher();
        String shipmentId = (String) context.get("shipmentId");
        String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId");
        Locale locale = (Locale) context.get("locale");
        
        Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale);
        String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId");
        String resource = (String) shipmentGatewayConfig.get("configProps");
        if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsGatewayNotAvailable", locale));
        }

        try {
            GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne();
            if (shipmentRouteSegment == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "ProductShipmentRouteSegmentNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            // ensure the carrier is USPS
            if (!"USPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsNotRouteSegmentCarrier", 
                        UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale));
            }

            // get the origin address
            GenericValue originAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress", false);
            if (originAddress == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentOriginPostalAddressNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            if (!"USA".equals(originAddress.getString("countryGeoId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsRouteSegmentOriginCountryGeoNotInUsa", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            String originZip = originAddress.getString("postalCode");
            if (UtilValidate.isEmpty(originZip)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsRouteSegmentOriginZipCodeMissing", 
                        UtilMisc.toMap("contactMechId", originAddress.getString("contactMechId")), locale));
            }

            // get the destination address
            GenericValue destinationAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress", false);
            if (destinationAddress == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentDestPostalAddressNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            if (!"USA".equals(destinationAddress.getString("countryGeoId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsRouteSegmentOriginCountryGeoNotInUsa", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            String destinationZip = destinationAddress.getString("postalCode");
            if (UtilValidate.isEmpty(destinationZip)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsRouteSegmentDestinationZipCodeMissing", 
                        UtilMisc.toMap("contactMechId", destinationAddress.getString("contactMechId")), locale));
            }

            // get the service type from the CarrierShipmentMethod
            String shipmentMethodTypeId = shipmentRouteSegment.getString("shipmentMethodTypeId");
            String partyId = shipmentRouteSegment.getString("carrierPartyId");
           
            GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod").where("partyId", partyId, "roleTypeId", "CARRIER", "shipmentMethodTypeId", shipmentMethodTypeId).queryOne();
            if (carrierShipmentMethod == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsNoCarrierShipmentMethod", 
                        UtilMisc.toMap("carrierPartyId", partyId, "shipmentMethodTypeId", shipmentMethodTypeId), locale));
            }
            String serviceType = carrierShipmentMethod.getString("carrierServiceCode");
            if (UtilValidate.isEmpty(serviceType)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsNoCarrierServiceCodeFound", 
                        UtilMisc.toMap("carrierPartyId", partyId, "shipmentMethodTypeId", shipmentMethodTypeId), locale));
            }

            // get the packages for this shipment route segment
            List<GenericValue> shipmentPackageRouteSegList = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false);
            if (UtilValidate.isEmpty(shipmentPackageRouteSegList)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentPackageRouteSegsNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            BigDecimal actualTransportCost = BigDecimal.ZERO;

            String carrierDeliveryZone = null;
            String carrierRestrictionCodes = null;
            String carrierRestrictionDesc = null;

            // send a new request for each package
            for (Iterator<GenericValue> i = shipmentPackageRouteSegList.iterator(); i.hasNext();) {

                GenericValue shipmentPackageRouteSeg = i.next();
                Document requestDocument = createUspsRequestDocument("RateRequest", true, delegator, shipmentGatewayConfigId, resource);

                Element packageElement = UtilXml.addChildElement(requestDocument.getDocumentElement(), "Package", requestDocument);
                packageElement.setAttribute("ID", "0");

                UtilXml.addChildElementValue(packageElement, "Service", serviceType, requestDocument);
                UtilXml.addChildElementValue(packageElement, "ZipOrigination", originZip, requestDocument);
                UtilXml.addChildElementValue(packageElement, "ZipDestination", destinationZip, requestDocument);

                GenericValue shipmentPackage = null;
                shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage", false);

                // weight elements - Pounds, Ounces
                String weightStr = shipmentPackage.getString("weight");
                if (UtilValidate.isEmpty(weightStr)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsWeightNotFound", 
                            UtilMisc.toMap("shipmentId", shipmentPackage.getString("shipmentId"), 
                                    "shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId")), locale));
                }

                BigDecimal weight = BigDecimal.ZERO;
                try {
                    weight = new BigDecimal(weightStr);
                } catch (NumberFormatException nfe) {
                    nfe.printStackTrace(); // TODO: handle exception
                }

                String weightUomId = shipmentPackage.getString("weightUomId");
                if (UtilValidate.isEmpty(weightUomId)) {
                    weightUomId = "WT_lb"; // assume weight is in pounds
                }
                if (!"WT_lb".equals(weightUomId)) {
                    // attempt a conversion to pounds
                    Map<String, Object> result = new HashMap<String, Object>();
                    try {
                        result = dispatcher.runSync("convertUom", UtilMisc.<String, Object>toMap("uomId", weightUomId, "uomIdTo", "WT_lb", "originalValue", weight));
                    } catch (GenericServiceException ex) {
                        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                                "FacilityShipmentUspsWeightConversionError", 
                                UtilMisc.toMap("errorString", ex.getMessage()), locale));
                    }

                    if (result.get(ModelService.RESPONSE_MESSAGE).equals(ModelService.RESPOND_SUCCESS) && result.get("convertedValue") != null) {
                        weight = weight.multiply((BigDecimal) result.get("convertedValue"));
                    } else {
                        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                                "FacilityShipmentUspsWeightUnsupported", 
                                UtilMisc.toMap("weightUomId", weightUomId, "shipmentId", shipmentPackage.getString("shipmentId"), 
                                        "shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"),
                                        "weightUom", "WT_lb"), locale));
                    }

                }

                BigDecimal weightPounds = weight.setScale(0, BigDecimal.ROUND_FLOOR);
                BigDecimal weightOunces = weight.multiply(new BigDecimal("16")).remainder(new BigDecimal("16")).setScale(0, BigDecimal.ROUND_CEILING);

                DecimalFormat df = new DecimalFormat("#");
                UtilXml.addChildElementValue(packageElement, "Pounds", df.format(weightPounds), requestDocument);
                UtilXml.addChildElementValue(packageElement, "Ounces", df.format(weightOunces), requestDocument);

                // Container element
                GenericValue carrierShipmentBoxType = null;
                List<GenericValue> carrierShipmentBoxTypes = null;
                carrierShipmentBoxTypes = shipmentPackage.getRelated("CarrierShipmentBoxType", UtilMisc.toMap("partyId", "USPS"), null, false);

                if (carrierShipmentBoxTypes.size() > 0) {
                    carrierShipmentBoxType = carrierShipmentBoxTypes.get(0);
                }

                if (carrierShipmentBoxType != null &&
                        UtilValidate.isNotEmpty(carrierShipmentBoxType.getString("packagingTypeCode"))) {
                    UtilXml.addChildElementValue(packageElement, "Container",
                            carrierShipmentBoxType.getString("packagingTypeCode"), requestDocument);
                } else {
                    // default to "None", for customers using their own package
                    UtilXml.addChildElementValue(packageElement, "Container", "None", requestDocument);
                }

                // Size element
                if (carrierShipmentBoxType != null && UtilValidate.isNotEmpty("oversizeCode")) {
                    UtilXml.addChildElementValue(packageElement, "Size",
                            carrierShipmentBoxType.getString("oversizeCode"), requestDocument);
                } else {
                    // default to "Regular", length + girth measurement <= 84 inches
                    UtilXml.addChildElementValue(packageElement, "Size", "Regular", requestDocument);
                }

                // Although only applicable for Parcel Post, this tag is required for all requests
                UtilXml.addChildElementValue(packageElement, "Machinable", "False", requestDocument);

                Document responseDocument = null;
                try {
                    responseDocument = sendUspsRequest("Rate", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
                } catch (UspsRequestException e) {
                    Debug.logInfo(e, module);
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsRateDomesticSendingError", 
                            UtilMisc.toMap("errorString", e.getMessage()), locale));
                }

                Element respPackageElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "Package");
                if (respPackageElement == null) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsRateDomesticResponseIncompleteElementPackage", locale));
                }

                Element respErrorElement = UtilXml.firstChildElement(respPackageElement, "Error");
                if (respErrorElement != null) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsRateDomesticResponseError", 
                            UtilMisc.toMap("errorString", UtilXml.childElementValue(respErrorElement, "Description")), locale));
                }

                // update the ShipmentPackageRouteSeg
                String postageString = UtilXml.childElementValue(respPackageElement, "Postage");
                if (UtilValidate.isEmpty(postageString)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsRateDomesticResponseIncompleteElementPostage", locale));
                }

                BigDecimal postage = BigDecimal.ZERO;
                try {
                    postage = new BigDecimal(postageString);
                } catch (NumberFormatException nfe) {
                    nfe.printStackTrace(); // TODO: handle exception
                }
                actualTransportCost = actualTransportCost.add(postage);

                shipmentPackageRouteSeg.setString("packageTransportCost", postageString);
                shipmentPackageRouteSeg.store();

                // if this is the last package, get the zone and APO/FPO restrictions for the ShipmentRouteSegment
                if (!i.hasNext()) {
                    carrierDeliveryZone = UtilXml.childElementValue(respPackageElement, "Zone");
                    carrierRestrictionCodes = UtilXml.childElementValue(respPackageElement, "RestrictionCodes");
                    carrierRestrictionDesc = UtilXml.childElementValue(respPackageElement, "RestrictionDescription");
                }
            }

            // update the ShipmentRouteSegment
            shipmentRouteSegment.set("carrierDeliveryZone", carrierDeliveryZone);
            shipmentRouteSegment.set("carrierRestrictionCodes", carrierRestrictionCodes);
            shipmentRouteSegment.set("carrierRestrictionDesc", carrierRestrictionDesc);
            shipmentRouteSegment.setString("actualTransportCost", String.valueOf(actualTransportCost));
            shipmentRouteSegment.store();

        } catch (GenericEntityException gee) {
            Debug.logInfo(gee, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsRateDomesticReadingError",
                    UtilMisc.toMap("errorString", gee.getMessage()), locale));
        }

        return ServiceUtil.returnSuccess();
    }

    /*

    Delivery Confirmation Samples:

    <DeliveryConfirmationV2.0Request USERID="xxxxxxx" PASSWORD="xxxxxxxx">
        <Option>3</Option>
        <ImageParameters></ImageParameters>
        <FromName>John Smith</FromName>
        <FromFirm>ABC Corp.</FromFirm>
        <FromAddress1>Ste  4</FromAddress1>
        <FromAddress2>6406  Ivy Lane</FromAddress2>
        <FromCity>Greenbelt</FromCity>
        <FromState>MD</FromState>
        <FromZip5>20770</FromZip5>
        <FromZip4>4354</FromZip4>
        <ToName>Jane Smith</ToName>
        <ToFirm>XYZ Corp.</ToFirm>
        <ToAddress1>Apt 303</ToAddress1>
        <ToAddress2>4411 Romlon Street</ToAddress2>
        <ToCity>Beltsville</ToCity>
        <ToState>MD</ToState>
        <ToZip5>20705</ToZip5>
        <ToZip4>5656</ToZip4>
        <WeightInOunces>22</WeightInOunces>
        <ServiceType>Parcel Post</ServiceType>
        <ImageType>TIF</ImageType>
    </DeliveryConfirmationV2.0Request>

    <DeliveryConfirmationV2.0Response>
        <DeliveryConfirmationNumber>02805213907052510758</DeliveryConfirmationNumber>
        <DeliveryConfirmationLabel>(Base64 encoded data)</DeliveryConfirmationLabel>
    </DeliveryConfirmationV2.0Response>

    */

    public static Map<String, Object> uspsDeliveryConfirmation(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        String shipmentId = (String) context.get("shipmentId");
        String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId");
        Locale locale = (Locale) context.get("locale");
        
        Map<String, Object> shipmentGatewayConfig = ShipmentServices.getShipmentGatewayConfigFromShipment(delegator, shipmentId, locale);
        String shipmentGatewayConfigId = (String) shipmentGatewayConfig.get("shipmentGatewayConfigId");
        String resource = (String) shipmentGatewayConfig.get("configProps");
        if (UtilValidate.isEmpty(shipmentGatewayConfigId) && UtilValidate.isEmpty(resource)) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsGatewayNotAvailable", locale));
        }

        try {
            GenericValue shipment = EntityQuery.use(delegator).from("Shipment").where("shipmentId", shipmentId).queryOne();
            if (shipment == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "ProductShipmentNotFoundId", locale) + shipmentId);
            }

            GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne();
            if (shipmentRouteSegment == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "ProductShipmentRouteSegmentNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            // ensure the carrier is USPS
            if (!"USPS".equals(shipmentRouteSegment.getString("carrierPartyId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsNotRouteSegmentCarrier", 
                        UtilMisc.toMap("shipmentRouteSegmentId", shipmentRouteSegmentId, "shipmentId", shipmentId), locale));
            }

            // get the origin address
            GenericValue originAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress", false);
            if (originAddress == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentOriginPostalAddressNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            if (!"USA".equals(originAddress.getString("countryGeoId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsRouteSegmentOriginCountryGeoNotInUsa", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            
            // get the destination address
            GenericValue destinationAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress", false);
            if (destinationAddress == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentRouteSegmentDestPostalAddressNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }
            if (!"USA".equals(destinationAddress.getString("countryGeoId"))) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsRouteSegmentOriginCountryGeoNotInUsa", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            // get the service type from the CarrierShipmentMethod
            String shipmentMethodTypeId = shipmentRouteSegment.getString("shipmentMethodTypeId");
            String partyId = shipmentRouteSegment.getString("carrierPartyId");

            GenericValue carrierShipmentMethod = EntityQuery.use(delegator).from("CarrierShipmentMethod").where("partyId", partyId, "roleTypeId", "CARRIER", "shipmentMethodTypeId", shipmentMethodTypeId).queryOne();
            if (carrierShipmentMethod == null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsNoCarrierShipmentMethod", 
                        UtilMisc.toMap("carrierPartyId", partyId, "shipmentMethodTypeId", shipmentMethodTypeId), locale));
            }
            String serviceType = carrierShipmentMethod.getString("carrierServiceCode");
            if (UtilValidate.isEmpty(serviceType)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsUnableDetermineServiceCode", locale));
            }

            // get the packages for this shipment route segment
            List<GenericValue> shipmentPackageRouteSegList = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false);
            if (UtilValidate.isEmpty(shipmentPackageRouteSegList)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentPackageRouteSegsNotFound", 
                        UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId), locale));
            }

            for (GenericValue shipmentPackageRouteSeg: shipmentPackageRouteSegList) {
                Document requestDocument = createUspsRequestDocument("DeliveryConfirmationV2.0Request", true, delegator, shipmentGatewayConfigId, resource);
                Element requestElement = requestDocument.getDocumentElement();

                UtilXml.addChildElementValue(requestElement, "Option", "3", requestDocument);
                UtilXml.addChildElement(requestElement, "ImageParameters", requestDocument);

                // From address
                if (UtilValidate.isNotEmpty(originAddress.getString("attnName"))) {
                    UtilXml.addChildElementValue(requestElement, "FromName", originAddress.getString("attnName"), requestDocument);
                    UtilXml.addChildElementValue(requestElement, "FromFirm", originAddress.getString("toName"), requestDocument);
                } else {
                    UtilXml.addChildElementValue(requestElement, "FromName", originAddress.getString("toName"), requestDocument);
                }
                // The following 2 assignments are not typos - USPS address1 = OFBiz address2, USPS address2 = OFBiz address1
                UtilXml.addChildElementValue(requestElement, "FromAddress1", originAddress.getString("address2"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "FromAddress2", originAddress.getString("address1"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "FromCity", originAddress.getString("city"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "FromState", originAddress.getString("stateProvinceGeoId"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "FromZip5", originAddress.getString("postalCode"), requestDocument);
                UtilXml.addChildElement(requestElement, "FromZip4", requestDocument);

                // To address
                if (UtilValidate.isNotEmpty(destinationAddress.getString("attnName"))) {
                    UtilXml.addChildElementValue(requestElement, "ToName", destinationAddress.getString("attnName"), requestDocument);
                    UtilXml.addChildElementValue(requestElement, "ToFirm", destinationAddress.getString("toName"), requestDocument);
                } else {
                    UtilXml.addChildElementValue(requestElement, "ToName", destinationAddress.getString("toName"), requestDocument);
                }
                // The following 2 assignments are not typos - USPS address1 = OFBiz address2, USPS address2 = OFBiz address1
                UtilXml.addChildElementValue(requestElement, "ToAddress1", destinationAddress.getString("address2"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "ToAddress2", destinationAddress.getString("address1"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "ToCity", destinationAddress.getString("city"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "ToState", destinationAddress.getString("stateProvinceGeoId"), requestDocument);
                UtilXml.addChildElementValue(requestElement, "ToZip5", destinationAddress.getString("postalCode"), requestDocument);
                UtilXml.addChildElement(requestElement, "ToZip4", requestDocument);

                GenericValue shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage", false);
                
                // WeightInOunces
                String weightStr = shipmentPackage.getString("weight");
                if (UtilValidate.isEmpty(weightStr)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsWeightNotFound", 
                            UtilMisc.toMap("shipmentId", shipmentPackage.getString("shipmentId"), 
                                    "shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId")), locale));
                }

                BigDecimal weight = BigDecimal.ZERO;
                try {
                    weight = new BigDecimal(weightStr);
                } catch (NumberFormatException nfe) {
                    nfe.printStackTrace(); // TODO: handle exception
                }

                String weightUomId = shipmentPackage.getString("weightUomId");
                if (UtilValidate.isEmpty(weightUomId)) {
                    // assume weight is in pounds for consistency (this assumption is made in uspsDomesticRate also)
                    weightUomId = "WT_lb";
                }
                if (!"WT_oz".equals(weightUomId)) {
                    // attempt a conversion to pounds
                    GenericValue uomConversion = EntityQuery.use(delegator).from("UomConversion").where("uomId", weightUomId, "uomIdTo", "WT_oz").queryOne();
                    if (uomConversion == null || UtilValidate.isEmpty(uomConversion.getString("conversionFactor"))) {
                        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                                "FacilityShipmentUspsWeightUnsupported", 
                                UtilMisc.toMap("weightUomId", weightUomId, "shipmentId", shipmentPackage.getString("shipmentId"), 
                                        "shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"),
                                        "weightUom", "WT_oz"), locale));
                    }
                    weight = weight.multiply(uomConversion.getBigDecimal("conversionFactor"));
                }

                DecimalFormat df = new DecimalFormat("#");
                UtilXml.addChildElementValue(requestElement, "WeightInOunces", df.format(weight.setScale(0, BigDecimal.ROUND_CEILING)), requestDocument);

                UtilXml.addChildElementValue(requestElement, "ServiceType", serviceType, requestDocument);
                UtilXml.addChildElementValue(requestElement, "ImageType", "TIF", requestDocument);
                UtilXml.addChildElementValue(requestElement, "AddressServiceRequested", "True", requestDocument);

                Document responseDocument = null;
                try {
                    responseDocument = sendUspsRequest("DeliveryConfirmationV2", requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
                } catch (UspsRequestException e) {
                    Debug.logInfo(e, module);
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsDeliveryConfirmationSendingError", 
                            UtilMisc.toMap("errorString", e.getMessage()), locale));
                }
                Element responseElement = responseDocument.getDocumentElement();

                Element respErrorElement = UtilXml.firstChildElement(responseElement, "Error");
                if (respErrorElement != null) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsDeliveryConfirmationResponseError", 
                            UtilMisc.toMap("shipmentId", shipmentPackage.getString("shipmentId"), 
                                    "shipmentPackageSeqId", shipmentPackage.getString("shipmentPackageSeqId"), 
                                    "errorString", UtilXml.childElementValue(respErrorElement, "Description")), locale));
                }

                String labelImageString = UtilXml.childElementValue(responseElement, "DeliveryConfirmationLabel");
                if (UtilValidate.isEmpty(labelImageString)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsDeliveryConfirmationResponseIncompleteElementDeliveryConfirmationLabel", locale));
                }
                shipmentPackageRouteSeg.setBytes("labelImage", Base64.base64Decode(labelImageString.getBytes()));
                String trackingCode = UtilXml.childElementValue(responseElement, "DeliveryConfirmationNumber");
                if (UtilValidate.isEmpty(trackingCode)) {
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsDeliveryConfirmationResponsenIncompleteElementDeliveryConfirmationNumber", locale));
                }
                shipmentPackageRouteSeg.set("trackingCode", trackingCode);
                shipmentPackageRouteSeg.store();
            }

        } catch (GenericEntityException gee) {
            Debug.logInfo(gee, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsDeliveryConfirmationReadingError", 
                    UtilMisc.toMap("errorString", gee.getMessage()), locale));
        }

        return ServiceUtil.returnSuccess();
    }

    /* ------------------------------------------------------------------------------------------------------------- */

    // testing utility service - remove this
    public static Map<String, Object> uspsDumpShipmentLabelImages(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();

        try {
            String shipmentId = (String) context.get("shipmentId");
            String shipmentRouteSegmentId = (String) context.get("shipmentRouteSegmentId");

            GenericValue shipmentRouteSegment = EntityQuery.use(delegator).from("ShipmentRouteSegment").where("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId).queryOne();

            List<GenericValue> shipmentPackageRouteSegList = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"), false);

            for (GenericValue shipmentPackageRouteSeg: shipmentPackageRouteSegList) {
                byte[] labelImageBytes = shipmentPackageRouteSeg.getBytes("labelImage");

                String outFileName = "UspsLabelImage" + shipmentRouteSegment.getString("shipmentId") + "_" +
                        shipmentRouteSegment.getString("shipmentRouteSegmentId") + "_" +
                        shipmentPackageRouteSeg.getString("shipmentPackageSeqId") + ".gif";

                FileOutputStream fileOut = new FileOutputStream(outFileName);
                fileOut.write(labelImageBytes);
                fileOut.flush();
                fileOut.close();
            }

        } catch (GenericEntityException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(e.getMessage());
        } catch (IOException e) {
            Debug.logInfo(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        return ServiceUtil.returnSuccess();
    }

    public static Map<String, Object> uspsPriorityMailInternationalLabel(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        LocalDispatcher dispatcher = dctx.getDispatcher();
        String shipmentGatewayConfigId = (String) context.get("shipmentGatewayConfigId");
        String resource = (String) context.get("configProps");
        GenericValue shipmentRouteSegment = (GenericValue) context.get("shipmentRouteSegment");
        Locale locale = (Locale) context.get("locale");

        // Start the document
        Document requestDocument;
        boolean certify = false;
        String test = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "test", resource, "shipment.usps.test");
        if (!"Y".equalsIgnoreCase(test)) {
            requestDocument = createUspsRequestDocument("PriorityMailIntlRequest", false, delegator, shipmentGatewayConfigId, resource);
        } else {
            requestDocument = createUspsRequestDocument("PriorityMailIntlCertifyRequest", false, delegator, shipmentGatewayConfigId, resource);
            certify = true;
        }
        Element rootElement = requestDocument.getDocumentElement();

        // Retrieve from/to address and package details
        GenericValue originAddress = null;
        GenericValue originTelecomNumber = null;
        GenericValue destinationAddress = null;
        GenericValue destinationProvince = null;
        GenericValue destinationCountry = null;
        GenericValue destinationTelecomNumber = null;
        List<GenericValue> shipmentPackageRouteSegs = null;
        try {
            originAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress", false);
            originTelecomNumber = shipmentRouteSegment.getRelatedOne("OriginTelecomNumber", false);
            destinationAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress", false);
            if (destinationAddress != null) {
                destinationProvince = destinationAddress.getRelatedOne("StateProvinceGeo", false);
                destinationCountry = destinationAddress.getRelatedOne("CountryGeo", false);
            }
            destinationTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber", false);
            shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, null, false);
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
        }
        if (originAddress == null || originTelecomNumber == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsPriorityMailLabelOriginAddressMissing", locale));
        }

        // Origin Info
        // USPS wants a separate first name and last, best we can do is split the string on the white space, if that doesn't work then default to putting the attnName in both fields
        String fromAttnName = originAddress.getString("attnName");
        String fromFirstName = StringUtils.defaultIfEmpty(StringUtils.substringBefore(fromAttnName, " "), fromAttnName);
        String fromLastName = StringUtils.defaultIfEmpty(StringUtils.substringAfter(fromAttnName, " "), fromAttnName);
        UtilXml.addChildElementValue(rootElement, "FromFirstName", fromFirstName, requestDocument);
        UtilXml.addChildElementValue(rootElement, "FromLastName", fromLastName, requestDocument);
        UtilXml.addChildElementValue(rootElement, "FromFirm", originAddress.getString("toName"), requestDocument);
        // The following 2 assignments are not typos - USPS address1 = OFBiz address2, USPS address2 = OFBiz address1
        UtilXml.addChildElementValue(rootElement, "FromAddress1", originAddress.getString("address2"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "FromAddress2", originAddress.getString("address1"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "FromCity", originAddress.getString("city"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "FromState", originAddress.getString("stateProvinceGeoId"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "FromZip5", originAddress.getString("postalCode"), requestDocument);
        // USPS expects a phone number consisting of area code + contact number as a single numeric string
        String fromPhoneNumber = originTelecomNumber.getString("areaCode") + originTelecomNumber.getString("contactNumber");
        fromPhoneNumber = StringUtil.removeNonNumeric(fromPhoneNumber);
        UtilXml.addChildElementValue(rootElement, "FromPhone", fromPhoneNumber, requestDocument);

        // Destination Info
        UtilXml.addChildElementValue(rootElement, "ToName", destinationAddress.getString("attnName"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "ToFirm", destinationAddress.getString("toName"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "ToAddress1", destinationAddress.getString("address1"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "ToAddress2", destinationAddress.getString("address2"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "ToCity", destinationAddress.getString("city"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "ToProvince", destinationProvince.getString("geoName"), requestDocument);
        // TODO: Test these country names, I think we're going to need to maintain a list of USPS names
        UtilXml.addChildElementValue(rootElement, "ToCountry", destinationCountry.getString("geoName"), requestDocument);
        UtilXml.addChildElementValue(rootElement, "ToPostalCode", destinationAddress.getString("postalCode"), requestDocument);
        // TODO: Figure out how to answer this question accurately
        UtilXml.addChildElementValue(rootElement, "ToPOBoxFlag", "N", requestDocument);
        String toPhoneNumber = destinationTelecomNumber.getString("countryCode") + destinationTelecomNumber.getString("areaCode") + destinationTelecomNumber.getString("contactNumber");
        UtilXml.addChildElementValue(rootElement, "ToPhone", toPhoneNumber, requestDocument);
        UtilXml.addChildElementValue(rootElement, "NonDeliveryOption", "RETURN", requestDocument);

        for (GenericValue shipmentPackageRouteSeg : shipmentPackageRouteSegs) {
            Document packageDocument = (Document) requestDocument.cloneNode(true);
            // This is our reference and can be whatever we want.  For lack of a better alternative we'll use shipmentId:shipmentPackageSeqId:shipmentRouteSegmentId
            String fromCustomsReference = shipmentRouteSegment.getString("shipmentId") + ":" + shipmentRouteSegment.getString("shipmentRouteSegmentId");
            fromCustomsReference = StringUtils.join(
                    UtilMisc.toList(
                            shipmentRouteSegment.get("shipmentId"),
                            shipmentPackageRouteSeg.get("shipmentPackageSeqId"),
                            shipmentRouteSegment.get("shipmentRouteSegementId")
                   ), ':');
            UtilXml.addChildElementValue(rootElement, "FromCustomsReference", fromCustomsReference, packageDocument);
            // Determine the container type for this package
            String container = "VARIABLE";
            String packageTypeCode = null;
            GenericValue shipmentPackage = null;
            List<GenericValue> shipmentPackageContents = null;
            try {
                shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage", false);
                shipmentPackageContents = shipmentPackage.getRelated("ShipmentPackageContent", null, null, false);
                GenericValue shipmentBoxType = shipmentPackage.getRelatedOne("ShipmentBoxType", false);
                if (shipmentBoxType != null) {
                    GenericValue carrierShipmentBoxType = EntityUtil.getFirst(shipmentBoxType.getRelated("CarrierShipmentBoxType", UtilMisc.toMap("partyId", "USPS"), null, false));
                    if (carrierShipmentBoxType != null) {
                        packageTypeCode = carrierShipmentBoxType.getString("packageTypeCode");
                        // Supported type codes
                        List<String> supportedPackageTypeCodes = UtilMisc.toList(
                                "LGFLATRATEBOX",
                                "SMFLATRATEBOX",
                                "FLATRATEBOX",
                                "MDFLATRATEBOX",
                                "FLATRATEENV");
                        if (supportedPackageTypeCodes.contains(packageTypeCode)) {
                            container = packageTypeCode;
                        }
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, module);
            }
            UtilXml.addChildElementValue(rootElement, "Container", container, packageDocument);
            // According to the docs sending an empty postage tag will cause the postage to be calculated
            UtilXml.addChildElementValue(rootElement, "Postage", "", packageDocument);

            BigDecimal packageWeight = shipmentPackage.getBigDecimal("weight");
            String weightUomId = shipmentPackage.getString("weightUomId");
            BigDecimal packageWeightPounds = UomWorker.convertUom(packageWeight, weightUomId, "WT_lb", dispatcher);
            Integer[] packagePoundsOunces = convertPoundsToPoundsOunces(packageWeightPounds);
            UtilXml.addChildElementValue(rootElement, "GrossPounds", packagePoundsOunces[0].toString(), packageDocument);
            UtilXml.addChildElementValue(rootElement, "GrossOunces", packagePoundsOunces[1].toString(), packageDocument);

            UtilXml.addChildElementValue(rootElement, "ContentType", "MERCHANDISE", packageDocument);
            UtilXml.addChildElementValue(rootElement, "Agreement", "N", packageDocument);
            UtilXml.addChildElementValue(rootElement, "ImageType", "PDF", packageDocument);
            // TODO: Try the different layouts
            UtilXml.addChildElementValue(rootElement, "ImageType", "ALLINONEFILE", packageDocument);
            UtilXml.addChildElementValue(rootElement, "CustomerRefNo", fromCustomsReference, packageDocument);

            // Add the shipping contents
            Element shippingContents = UtilXml.addChildElement(rootElement, "ShippingContents", packageDocument);
            for (GenericValue shipmentPackageContent : shipmentPackageContents) {
                Element itemDetail = UtilXml.addChildElement(shippingContents, "ItemDetail", packageDocument);
                GenericValue product = null;
                GenericValue originGeo = null;
                try {
                    GenericValue shipmentItem = shipmentPackageContent.getRelatedOne("ShipmentItem", false);
                    product = shipmentItem.getRelatedOne("Product", false);
                    originGeo = product.getRelatedOne("OriginGeo", false);
                } catch (GenericEntityException e) {
                    Debug.logInfo(e, module);
                }

                UtilXml.addChildElementValue(itemDetail, "Description", product.getString("productName"), packageDocument);
                UtilXml.addChildElementValue(itemDetail, "Quantity", shipmentPackageContent.getBigDecimal("quantity").setScale(0, BigDecimal.ROUND_CEILING).toPlainString(), packageDocument);
                String packageContentValue = ShipmentWorker.getShipmentPackageContentValue(shipmentPackageContent).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
                UtilXml.addChildElementValue(itemDetail, "Value", packageContentValue, packageDocument);
                BigDecimal productWeight = ProductWorker.getProductWeight(product, "WT_lbs", delegator, dispatcher);
                Integer[] productPoundsOunces = convertPoundsToPoundsOunces(productWeight);
                UtilXml.addChildElementValue(itemDetail, "NetPounds", productPoundsOunces[0].toString(), packageDocument);
                UtilXml.addChildElementValue(itemDetail, "NetOunces", productPoundsOunces[1].toString(), packageDocument);
                UtilXml.addChildElementValue(itemDetail, "HSTariffNumber", "", packageDocument);
                UtilXml.addChildElementValue(itemDetail, "CountryOfOrigin", originGeo.getString("geoName"), packageDocument);
            }

            // Send the request
            Document responseDocument = null;
            String api = certify ? "PriorityMailIntlCertify" : "PriorityMailIntl";
            try {
                responseDocument = sendUspsRequest(api, requestDocument, delegator, shipmentGatewayConfigId, resource, locale);
            } catch (UspsRequestException e) {
                Debug.logInfo(e, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsPriorityMailLabelSendingError", 
                        UtilMisc.toMap("errorString", e.getMessage()), locale));
            }
            Element responseElement = responseDocument.getDocumentElement();

            // TODO: No mention of error returns in the docs

            String labelImageString = UtilXml.childElementValue(responseElement, "LabelImage");
            if (UtilValidate.isEmpty(labelImageString)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsPriorityMailLabelResponseIncompleteElementLabelImage", locale));
            }
            shipmentPackageRouteSeg.setBytes("labelImage", Base64.base64Decode(labelImageString.getBytes()));
            String trackingCode = UtilXml.childElementValue(responseElement, "BarcodeNumber");
            if (UtilValidate.isEmpty(trackingCode)) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "FacilityShipmentUspsPriorityMailLabelResponseIncompleteElementBarcodeNumber", locale));
            }
            shipmentPackageRouteSeg.set("trackingCode", trackingCode);
            try {
                shipmentPackageRouteSeg.store();
            } catch (GenericEntityException e) {
                Debug.logError(e, module);
            }

        }
        return ServiceUtil.returnSuccess();
    }

    private static Document createUspsRequestDocument(String rootElement, boolean passwordRequired, Delegator delegator, String shipmentGatewayConfigId, String resource) {
        Document requestDocument = UtilXml.makeEmptyXmlDocument(rootElement);
        Element requestElement = requestDocument.getDocumentElement();
        requestElement.setAttribute("USERID", getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, 
                "accessUserId", resource, "shipment.usps.access.userid", ""));
        if (passwordRequired) {
            requestElement.setAttribute("PASSWORD", getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, 
                    "accessPassword", resource, "shipment.usps.access.password", ""));
        }
        return requestDocument;
    }

    private static Document sendUspsRequest(String requestType, Document requestDocument, Delegator delegator,
            String shipmentGatewayConfigId, String resource, Locale locale) throws UspsRequestException {
        String conUrl = null;
        List<String> labelRequestTypes = UtilMisc.toList("PriorityMailIntl", "PriorityMailIntlCertify");
        if (labelRequestTypes.contains(requestType)) {
            conUrl = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectUrlLabels", resource, "shipment.usps.connect.url.labels");
        } else {
            conUrl = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectUrl", resource, "shipment.usps.connect.url");
        }
        if (UtilValidate.isEmpty(conUrl)) {
            throw new UspsRequestException(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsConnectUrlIncomplete", locale));
        }

        OutputStream os = new ByteArrayOutputStream();

        try {
            UtilXml.writeXmlDocument(requestDocument, os, "UTF-8", true, false, 0);
        } catch (TransformerException e) {
            throw new UspsRequestException(
                    UtilProperties.getMessage(resourceError, 
                            "FacilityShipmentUspsSerializingError",
                            UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        String xmlString = os.toString();

        Debug.logInfo("USPS XML request string: " + xmlString, module);

        String timeOutStr = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, "connectTimeout", 
                resource, "shipment.usps.connect.timeout", "60");
        int timeout = 60;
        try {
            timeout = Integer.parseInt(timeOutStr);
        } catch (NumberFormatException e) {
            Debug.logError(e, "Unable to set timeout to " + timeOutStr + " using default " + timeout);
        }

        HttpClient http = new HttpClient(conUrl);
        http.setTimeout(timeout * 1000);
        http.setParameter("API", requestType);
        http.setParameter("XML", xmlString);

        String responseString = null;
        try {
            responseString = http.get();
        } catch (HttpClientException e) {
            throw new UspsRequestException(UtilProperties.getMessage(resourceError, 
                    "FacilityShipmentUspsConnectionProblem",
                    UtilMisc.toMap("errorString", e), locale));
        }

        Debug.logInfo("USPS response: " + responseString, module);

        if (UtilValidate.isEmpty(responseString)) {
            return null;
        }

        Document responseDocument = null;
        try {
            responseDocument = UtilXml.readXmlDocument(responseString, false);
        } catch (Exception e) {
            throw new UspsRequestException(UtilProperties.getMessage(resourceError, "FacilityShipmentUspsResponseError", UtilMisc.toMap("errorString", e.getMessage()), locale));
        }

        // If a top-level error document is returned, throw exception
        // Other request-level errors should be handled by the caller
        Element responseElement = responseDocument.getDocumentElement();
        if ("Error".equals(responseElement.getNodeName())) {
            throw new UspsRequestException(UtilXml.childElementValue(responseElement, "Description"));
        }

        return responseDocument;
    }

    /*
     * Converts decimal pounds to pounds and ounces as an Integer array, ounces are rounded up to the nearest whole number
     */
    public static Integer[] convertPoundsToPoundsOunces(BigDecimal decimalPounds) {
        if (decimalPounds == null) return null;
        Integer[] poundsOunces = new Integer[2];
        poundsOunces[0] = Integer.valueOf(decimalPounds.setScale(0, BigDecimal.ROUND_FLOOR).toPlainString());
        // (weight % 1) * 16 rounded up to nearest whole number
        poundsOunces[1] = Integer.valueOf(decimalPounds.remainder(BigDecimal.ONE).multiply(new BigDecimal("16")).setScale(0, BigDecimal.ROUND_CEILING).toPlainString());
        return poundsOunces;
    }
    
    private static String getShipmentGatewayConfigValue(Delegator delegator, String shipmentGatewayConfigId, String shipmentGatewayConfigParameterName, 
            String resource, String parameterName) {
        String returnValue = "";
        if (UtilValidate.isNotEmpty(shipmentGatewayConfigId)) {
            try {
                GenericValue usps = EntityQuery.use(delegator).from("ShipmentGatewayUsps").where("shipmentGatewayConfigId", shipmentGatewayConfigId).queryOne();
                if (usps != null) {
                    Object uspsField = usps.get(shipmentGatewayConfigParameterName);
                    if (uspsField != null) {
                        returnValue = uspsField.toString().trim();
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, module);
            }
        } else {
            String value = EntityUtilProperties.getPropertyValue(resource, parameterName, delegator);
            if (value != null) {
                returnValue = value.trim();
            }
        }
        return returnValue;
    }
        
    private static String getShipmentGatewayConfigValue(Delegator delegator, String shipmentGatewayConfigId, String shipmentGatewayConfigParameterName, 
            String resource, String parameterName, String defaultValue) {
        String returnValue = getShipmentGatewayConfigValue(delegator, shipmentGatewayConfigId, shipmentGatewayConfigParameterName, resource, parameterName);
        if (UtilValidate.isEmpty(returnValue)) {
            returnValue = defaultValue;
        }
        return returnValue;
    }
}

@SuppressWarnings("serial")
class UspsRequestException extends GeneralException {
    UspsRequestException() {
        super();
    }

    UspsRequestException(String msg) {
        super(msg);
    }

    UspsRequestException(Throwable t) {
        super(t);
    }

    UspsRequestException(String msg, Throwable t) {
        super(msg, t);
    }
}
