The 1.4 version of USPSComputationMethod.cs is very broken when it comes to multi-package support (including a TODO comment that says as much). I've updated it, but I don't know how relavent it is to NC1.5, so I'll post it here:

// USPSComputationMethod.cs
//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  https://www.nopcommerce.com/License.aspx.
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
//
// Contributor(s): RJH 08/07/2009.
// csells 5/13/2010.
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml;
using NopSolutions.NopCommerce.BusinessLogic;
using NopSolutions.NopCommerce.BusinessLogic.Configuration.Settings;
using NopSolutions.NopCommerce.BusinessLogic.Measures;
using NopSolutions.NopCommerce.BusinessLogic.Shipping;
using NopSolutions.NopCommerce.Common;

namespace NopSolutions.NopCommerce.Shipping.Methods.USPS {
  /// <summary>
  /// US Postal Service computation method
  /// </summary>
  public class USPSComputationMethod : IShippingRateComputationMethod {
    #region Const

    private const decimal MAXPACKAGEWEIGHT = 70;
    //private const decimal MAXPACKAGESIZE = 130; // Oversize doesn't work for Priority or Express
    private const decimal MAXPACKAGESIZE = 108; // Large is the largest we can do

    #endregion
    #region Utilities

    private string CreateRequest(string Username, string Password, ShipmentPackage ShipmentPackage, out int totalPackages) {
      decimal length = ShipmentPackage.GetTotalLength();
      decimal height = Math.Ceiling(ShipmentPackage.GetTotalHeight());
      decimal width = Math.Ceiling(ShipmentPackage.GetTotalWidth());
      decimal weight = ShippingManager.GetShoppingCartTotalWeigth(ShipmentPackage.Items);
      string zipPostalCodeFrom = ShipmentPackage.ZipPostalCodeFrom;
      string zipPostalCodeTo = ShipmentPackage.ShippingAddress.ZipPostalCode;

      //TODO convert measure weight
      MeasureWeight baseWeightIn = MeasureManager.BaseWeightIn;
      if (baseWeightIn.SystemKeyword != "lb")
        throw new NopException("USPS shipping service. Base weight should be set to lb(s)");

      //TODO convert measure dimension
      MeasureDimension baseDimensionIn = MeasureManager.BaseDimensionIn;
      if (baseDimensionIn.SystemKeyword != "inches")
        throw new NopException("USPS shipping service. Base dimension should be set to inch(es)");

      // NOTE: round up to next heavier pounds for USPS
      //decimal pounds = Convert.ToInt32(Math.Truncate(weight));
      //decimla ounces = Convert.ToInt32((weight - pounds) * 16.0M);
      decimal pounds = Math.Ceiling(weight);
      decimal ounces = 0;

      StringBuilder sb = new StringBuilder();
      sb.AppendFormat("<RateV3Request USERID=\"{0}\" PASSWORD=\"{1}\">", Username, Password);

      var packageSize = USPSPackageSize.TooLarge;

      if (IsPackageTooHeavy(pounds) || IsPackageTooLarge(length, height, width)) {
        decimal totalPackagesSize = TotalPackageSize(length, height, width);
        int totalPackagesByDims = Convert.ToInt32(Math.Ceiling(totalPackagesSize / MAXPACKAGESIZE));
        int totalPackagesByWeight = Convert.ToInt32(Math.Ceiling(pounds / MAXPACKAGEWEIGHT));

        totalPackages = Math.Max(Math.Max(totalPackagesByDims, totalPackagesByWeight), 1);
        pounds = Math.Ceiling(pounds / (decimal)totalPackages);
        ounces = Math.Ceiling(ounces / (decimal)totalPackages);
        packageSize = GetPackageSize(totalPackagesSize / (decimal)totalPackages);
      }
      else {
        totalPackages = 1;
        packageSize = GetPackageSize(length, height, width);
      }

      // NOTE: this shouldn't happen
      if (packageSize == USPSPackageSize.TooLarge) { throw new NopException("Shipping Error: Package too large."); }

      // NOTE: instead of filtering by service from USPSStrings.Elements the way the original code was doing,
      // we're asking for All potential shipping service rates to be calculated. This is because USPS errors on
      // certain size/weight/service combindations. On the other hand, if we just give it size/weight info,
      // it'll tell us which services are available, which we then post-filter using USPSStrings.Names.
      sb.Append("<Package ID=\"0\">");
      sb.Append("<Service>All</Service>");
      sb.AppendFormat("<ZipOrigination>{0}</ZipOrigination>", zipPostalCodeFrom);
      sb.AppendFormat("<ZipDestination>{0}</ZipDestination>", zipPostalCodeTo);
      sb.AppendFormat("<Pounds>{0}</Pounds>", pounds);
      sb.AppendFormat("<Ounces>{0}</Ounces>", ounces);
      sb.AppendFormat("<Size>{0}</Size>", packageSize);
      sb.Append("<Machinable>FALSE</Machinable>");
      sb.Append("</Package>");

      sb.Append("</RateV3Request>");
      return "API=RateV3&XML=" + sb.ToString();
    }

    private string DoRequest(string URL, string RequestString) {
      byte[] bytes = new ASCIIEncoding().GetBytes(RequestString);
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
      request.Method = "POST";
      request.ContentType = "application/x-www-form-urlencoded";
      request.ContentLength = bytes.Length;
      Stream requestStream = request.GetRequestStream();
      requestStream.Write(bytes, 0, bytes.Length);
      requestStream.Close();
      WebResponse response = request.GetResponse();
      string responseXML = string.Empty;
      using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        responseXML = reader.ReadToEnd();

      return responseXML;
    }

    private bool IsPackageTooLarge(decimal length, decimal height, decimal width) {
      return TotalPackageSize(length, height, width) > MAXPACKAGESIZE;
    }

    private decimal TotalPackageSize(decimal length, decimal height, decimal width) {
      return (height + height + width + width) + length; // girth + length
    }

    private bool IsPackageTooHeavy(decimal weight) {
      return weight > MAXPACKAGEWEIGHT;
    }

    private USPSPackageSize GetPackageSize(decimal length, decimal height, decimal width) {
      return GetPackageSize(TotalPackageSize(length, height, width));
    }

    private USPSPackageSize GetPackageSize(decimal total) {
      if (total <= 84) { return USPSPackageSize.Regular; }
      else if ((total > 84) && (total <= 108)) { return USPSPackageSize.Large; }
      else if ((total > 108) && (total <= 130)) { return USPSPackageSize.Oversize; }
      else { return USPSPackageSize.TooLarge; }
    }

    private ShippingOptionCollection ParseResponse(string response, ref string error) {
      ShippingOptionCollection shippingOptions = new ShippingOptionCollection();

      using (StringReader sr = new StringReader(response))
      using (XmlTextReader tr = new XmlTextReader(sr))


        do {
          // Read the next XML record
          tr.Read();

          if ((tr.Name == "Error") && (tr.NodeType == XmlNodeType.Element)) {
            string errorText = "";
            while (tr.Read()) {
              if ((tr.Name == "Description") && (tr.NodeType == XmlNodeType.Element))
                errorText += "Error Desc: " + tr.ReadString();
              if ((tr.Name == "HelpContext") && (tr.NodeType == XmlNodeType.Element))
                errorText += "USPS Help Context: " + tr.ReadString() + ". ";
            }
            error = "USPS Error returned: " + errorText;
          }

          // Process the inner postage XML
          if ((tr.Name == "Postage") && (tr.NodeType == XmlNodeType.Element)) {
            string serviceCode = "";
            string postalRate = "";

            do {

              tr.Read();

              if ((tr.Name == "MailService") && (tr.NodeType == XmlNodeType.Element)) {
                serviceCode = tr.ReadString();

                tr.ReadEndElement();
                if ((tr.Name == "MailService") && (tr.NodeType == XmlNodeType.EndElement))
                  break;
              }
              // if (((tr.Name == "Postage") && (tr.NodeType == XmlNodeType.EndElement)) || ((tr.Name == "Postage") && (tr.NodeType == XmlNodeType.Element)))
              //   break;

              if ((tr.Name == "Rate") && (tr.NodeType == XmlNodeType.Element)) {
                postalRate = tr.ReadString();
                tr.ReadEndElement();
                if ((tr.Name == "Rate") && (tr.NodeType == XmlNodeType.EndElement))
                  break;
              }

            } while (!((tr.Name == "Postage") && (tr.NodeType == XmlNodeType.EndElement)));

            if (shippingOptions.Find((s) => s.Name == serviceCode) == null) {
              ShippingOption shippingOption = new ShippingOption();
              shippingOption.Rate = Convert.ToDecimal(postalRate, new CultureInfo("en-US"));
              shippingOption.Name = serviceCode;
              shippingOptions.Add(shippingOption);
            }
          }
        } while (!tr.EOF);
      return shippingOptions;
    }

    #endregion

    #region Methods
    /// <summary>
    ///  Gets available shipping options
    /// </summary>
    /// <param name="ShipmentPackage">Shipment option</param>
    /// <param name="Error">Error</param>
    /// <returns>Shipping options</returns>
    public ShippingOptionCollection GetShippingOptions(ShipmentPackage ShipmentPackage, ref string Error) {
      ShippingOptionCollection shippingOptions = new ShippingOptionCollection();

      if (ShipmentPackage == null)
        throw new ArgumentNullException("ShipmentPackage");
      if (ShipmentPackage.Items == null)
        throw new NopSolutions.NopCommerce.Common.NopException("No shipment items");
      if (ShipmentPackage.ShippingAddress == null) {
        Error = "Shipping address is not set";
        return shippingOptions;
      }

      string url = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.URL");
      string username = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.Username");
      string password = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.Password");
      decimal additionalHandlingCharge = SettingManager.GetSettingValueDecimalNative("ShippingRateComputationMethod.USPS.AdditionalHandlingCharge");
      ShipmentPackage.ZipPostalCodeFrom = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.DefaultShippedFromZipPostalCode");
      int totalPackages;
      string requestString = CreateRequest(username, password, ShipmentPackage, out totalPackages);
      string responseXML = DoRequest(url, requestString);
      shippingOptions = new ShippingOptionCollection();

      // filter for allowed options and adjust rates based on total number of packages
      USPSStrings uspsStrings = new USPSStrings();
      foreach (var option in ParseResponse(responseXML, ref Error)) {
        if (uspsStrings.Names.Any(service => string.Compare(service, option.Name, true) == 0)) {
          shippingOptions.Add(option);
          option.Rate = option.Rate * totalPackages + additionalHandlingCharge;
        }
      }

      if (String.IsNullOrEmpty(Error) && shippingOptions.Count == 0)
        Error = "Shipping options could not be loaded";
      return shippingOptions;
    }

    /// <summary>
    /// Gets fixed shipping rate (if shipping rate computation method allows it and the rate can be calculated before checkout).
    /// </summary>
    /// <param name="ShipmentPackage">Shipment package</param>
    /// <returns>Fixed shipping rate; or null if shipping rate could not be calculated before checkout</returns>
    public decimal? GetFixedRate(ShipmentPackage ShipmentPackage) {
      return null;
    }
    #endregion
  }
}


Also, my USPSPackageSize.cs and USPSStrings.cs files are different, too:

//USPSPackageSize.cs
//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  https://www.nopcommerce.com/License.aspx.
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
//
// Contributor(s): _______.
// csells 5/13/2010.
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml;
using NopSolutions.NopCommerce.BusinessLogic.Shipping;

namespace NopSolutions.NopCommerce.Shipping.Methods.USPS {
  internal enum USPSPackageSize {
    Regular,
    Large,
    Oversize,
    TooLarge,
  }
}

// USPSStrings.cs
//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  https://www.nopcommerce.com/License.aspx.
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
//
// Contributor(s): RJH 08/07/2009.
// csells 5/13/2010.
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml;
using NopSolutions.NopComme