public static ManuQuote calculateReverseEngineeringQuote(
      Blueprint t3Bpo,
      int runs,
      ManuQuote oldQuote,
      PriceDB pdb,
      BlueprintDB bdb,
      ItemDB idb,
      Preferences prefs,
      RevPriority rPrio,
      MatAcquirePriority mPrio) {
    // Combination list.
    ArrayList<ManuQuote> qL = new ArrayList<>();
    ManuQuote tmp = null;
    Blueprint cleanT3Bpo = bdb.getByBlueprintId(t3Bpo.getBlueprintItem().getTypeId());

    for (Relic rel : cleanT3Bpo.getRevRelics()) {

      // Only add quote if relic is available.
      if (MarketCalculator.isItemAvailable(rel.getRelic(), pdb, prefs)) {
        tmp =
            calculateQuote(
                calculateReverseEngineeringBPC(cleanT3Bpo, rel, idb, prefs),
                runs,
                oldQuote,
                pdb,
                bdb,
                prefs,
                mPrio);
        tmp.setRev(
            new ReverseEngineering(
                calculateReverseEngineeringChance(cleanT3Bpo, rel, idb, prefs),
                cleanT3Bpo.getRevDecryptor(),
                rel.getRevMaxRunModifier(),
                new Time(DEFAULT_REV_TIME),
                rPrio));
        qL.add(tmp);
      }
    }

    // Pick the best Quote according to priority.
    for (ManuQuote q : qL) {
      if (rPrio == RevPriority.PROFIT_MARGIN && q.getProfit() > tmp.getProfit()) {
        tmp = q;
      } else if (rPrio == RevPriority.PROFIT_PER_REV_H
          && q.getProfit()
                  / (q.getRev().getRevTime().toHours()
                      * q.getRev().getBpcRuns()
                      * q.getRev().getSuccessRate())
              > tmp.getProfit()
                  / (tmp.getRev().getRevTime().toHours()
                      * tmp.getRev().getBpcRuns()
                      * tmp.getRev().getSuccessRate())) {
        tmp = q;
      }
    }
    return tmp;
  }
  public static ManuQuote calculateInventionQuote(
      Blueprint t2Bpo,
      int runs,
      ManuQuote oldQuote,
      PriceDB pdb,
      TechDB tdb,
      BlueprintDB bdb,
      Preferences prefs,
      InvPriority iPrio,
      MatAcquirePriority mPrio) {

    // Corresponding T1 blueprint.
    Blueprint t1Bpo = bdb.getByProductId(tdb.getParentId(t2Bpo.getProduct()));
    Blueprint cleanT2Bpo = bdb.getByBlueprintId(t2Bpo.getBlueprintItem().getTypeId());

    // Variations.
    ArrayList<Decryptor> dL = t1Bpo.getInvDecryptors();
    dL.add(null); // No decryptor.
    ArrayList<Item> iL = tdb.getT1Items(t1Bpo.getProduct().getTypeId());
    iL.add(null); // No item.
    int[] rL = {1, t1Bpo.getMaxRuns()};

    // Combination list.
    ArrayList<ManuQuote> qL = new ArrayList<>();
    ManuQuote tmp = null;

    for (int t1BpcRuns : rL) {
      for (Item metaItem : iL) {
        for (Decryptor dec : dL) {

          // Only add quote if decryptor is available.
          if (dec == null || MarketCalculator.isItemAvailable(dec.getDecryptor(), pdb, prefs)) {

            // Get quote.
            tmp =
                calculateQuote(
                    calculateInventionBPC(t1Bpo, cleanT2Bpo, metaItem, t1BpcRuns, dec, prefs),
                    runs,
                    oldQuote,
                    pdb,
                    bdb,
                    prefs,
                    mPrio);
            tmp.setInv(
                new Invention(
                    calculateInventionChance(t1Bpo, metaItem, dec, prefs),
                    dec,
                    metaItem,
                    t1BpcRuns,
                    new Time(
                        (int)
                            (((t1Bpo.getCopyTime() * t1BpcRuns / (double) t1Bpo.getMaxRuns()) + 0.5)
                                * MOD_COPY_VALUE[
                                    prefs.getInstallationModIndex(
                                        InstallationMod
                                            .SLOT_MOD_COPY)])), // Divide copyTime with number of
                                                                // max-runs.
                    calculateInventionBPCRuns(t1Bpo, cleanT2Bpo, t1BpcRuns, dec),
                    new Time(0, 0, 0, calculateInventionTime(t1Bpo, prefs)),
                    iPrio));

            qL.add(tmp);
          }
        }
      }
    }

    // Pick the best Quote according to priority.
    for (ManuQuote q : qL) {
      if (iPrio == InvPriority.PROFIT_MARGIN && q.getProfit() > tmp.getProfit()) {
        tmp = q;
      } else if (iPrio == InvPriority.PROFIT_PER_H
          && q.getProfitPerHour() > tmp.getProfitPerHour()) {
        tmp = q;
      } else if (iPrio == InvPriority.PROFIT_PER_COPY_H
          && q.getProfit()
                  / (q.getInv().getCopyTime().toHours()
                      * q.getInv().getT2BpcRuns()
                      * q.getInv().getSuccessRate())
              > tmp.getProfit()
                  / (tmp.getInv().getCopyTime().toHours()
                      * tmp.getInv().getT2BpcRuns()
                      * tmp.getInv().getSuccessRate())) {
        tmp = q;
      } else if (iPrio == InvPriority.PROFIT_SUSTAINED
          && q.getSustainableProfitValue() > tmp.getSustainableProfitValue()) {
        tmp = q;
      }
    }
    // Set the T1 BPO market availability.
    tmp.setBaseBPOSeededOnMarket(
        MarketCalculator.isItemAvailable(t1Bpo.getBlueprintItem(), pdb, prefs));

    return tmp;
  }