private void createPriceData(final int typeID, final Pricing pricing) {
   PriceData priceData = priceDataList.get(typeID);
   if (priceData == null) {
     priceData = new PriceData();
     priceDataList.put(typeID, priceData);
   }
   boolean ok = false;
   for (PriceMode priceMode : PriceMode.values()) {
     PricingType pricingType = priceMode.getPricingType();
     PricingNumber pricingNumber = priceMode.getPricingNumber();
     if (pricingNumber == null || pricingType == null) {
       continue; // Ignore calculated prices - f.ex. PriceMode.PRICE_MIDPOINT
     }
     Double price = pricing.getPrice(typeID, pricingType, pricingNumber);
     if (price != null) {
       ok = true; // Something is set
       PriceMode.setDefaultPrice(priceData, priceMode, price);
     }
   }
   if (ok) {
     getQueue().remove(typeID); // Load price...
     okay.add(typeID);
     failed.remove(typeID);
   } else {
     failed.add(typeID);
   }
   long nextUpdateTemp = pricing.getNextUpdateTime(typeID);
   if (nextUpdateTemp >= 0 && nextUpdateTemp > nextUpdate) {
     nextUpdate = nextUpdateTemp;
   }
   if (updateTask != null) {
     updateTask.setTaskProgress(typeIDs.size(), okay.size(), 0, 100);
   }
   if (!okay.isEmpty() && !typeIDs.isEmpty()) {
     SplashUpdater.setSubProgress((int) (okay.size() * 100.0 / typeIDs.size()));
   }
 }
  /**
   * @param task UpdateTask to update progress on
   * @param updateAll true to update all prices. false to only update new/missing prices
   * @param pricingOptions Options used doing update
   * @param typeIDs TypeIDs to get price data for
   * @param priceSource Price data source to update from (only used in log)
   * @return
   */
  protected Map<Integer, PriceData> processUpdate(
      final UpdateTask task,
      final boolean updateAll,
      final PricingOptions pricingOptions,
      final Set<Integer> typeIDs,
      final PriceSource priceSource) {
    this.updateTask = task;
    this.update = updateAll;
    this.typeIDs = new HashSet<Integer>(typeIDs);
    this.failed = new HashSet<Integer>();
    this.okay = new HashSet<Integer>();
    this.queue = new HashSet<Integer>(typeIDs);
    this.priceDataList = new HashMap<Integer, PriceData>();

    if (updateAll) {
      LOG.info("Price data update all (" + priceSource + "):");
    } else {
      LOG.info("Price data update new (" + priceSource + "):");
    }

    Pricing pricing = PricingFactory.getPricing(pricingOptions);

    // Reset cache timers...
    if (updateAll) {
      for (int id : typeIDs) {
        pricing.setPrice(id, -1.0);
      }
    }
    pricing.addPricingListener(this);

    // Load price data (Update as needed)
    for (int id : typeIDs) {
      createPriceData(id, pricing);
    }
    while (!getQueue().isEmpty()) {
      try {
        synchronized (this) {
          wait();
        }
      } catch (InterruptedException ex) {
        LOG.info("Failed to update price");
        pricing.cancelAll();
        if (updateTask != null) {
          updateTask.addError("Price data", "Cancelled");
          updateTask.setTaskProgress(100, 100, 0, 100);
          updateTask = null;
        }
        clear(pricing);
        return null;
      }
    }
    if (!failed.isEmpty()) {
      StringBuilder errorString = new StringBuilder();
      for (int typeID : failed) {
        if (!errorString.toString().isEmpty()) {
          errorString.append(", ");
        }
        errorString.append(typeID);
      }
      LOG.error("Failed to update price data for the following typeIDs: " + errorString.toString());
      if (updateTask != null) {
        updateTask.addError(
            "Price data", "Failed to update price data for " + failed.size() + " item types");
      }
    }
    boolean updated = (!priceDataList.isEmpty() && (typeIDs.size() * 5 / 100) > failed.size()); //
    if (updated) { // All Updated
      if (updateAll) {
        LOG.info("	Price data updated");
      } else {
        LOG.info("	Price data loaded");
      }
      try {
        pricing.writeCache();
        LOG.info("	Price data cached saved");
      } catch (IOException ex) {
        LOG.error("Failed to write price data cache", ex);
      }
      // We only set the price data if everthing worked (AKA all updated)
      try {
        // return new HashMap<Integer, PriceData>(priceDataList);
        // XXX - Workaround for ConcurrentModificationException in HashMap constructor
        Map<Integer, PriceData> hashMap = new HashMap<Integer, PriceData>();
        priceDataList.keySet().removeAll(failed);
        hashMap.putAll(priceDataList);
        return hashMap;
      } finally {
        clear(pricing);
      }
    } else { // None or some updated
      LOG.info("	Failed to update price data");
      if (updateTask != null) {
        updateTask.addError("Price data", "Failed to update price data");
        updateTask.setTaskProgress(100, 100, 0, 100);
      }
      clear(pricing);
      return null;
    }
  }