class BlackScholesFormulaRepository {

  public static double dualCharm(
      double spot,
      double strike,
      double timeToExpiry,
      double lognormalVol,
      double interestRate,
      double costOfCarry,
      boolean isCall) {

    ArgChecker.isTrue(spot >= 0d, "negative/NaN spot; have {}", spot);
    ArgChecker.isTrue(strike >= 0d, "negative/NaN strike; have {}", strike);
    ArgChecker.isTrue(timeToExpiry >= 0d, "negative/NaN timeToExpiry; have {}", timeToExpiry);
    ArgChecker.isTrue(lognormalVol >= 0d, "negative/NaN lognormalVol; have {}", lognormalVol);
    ArgChecker.isFalse(Double.isNaN(interestRate), "interestRate is NaN");
    ArgChecker.isFalse(Double.isNaN(costOfCarry), "costOfCarry is NaN");

    double rootT = Math.sqrt(timeToExpiry);
    double sigmaRootT = lognormalVol * rootT;
    if (Double.isNaN(sigmaRootT)) {
      sigmaRootT = 1d; //ref value is returned
    }

    double discount = Math.exp(-interestRate * timeToExpiry);
    if (discount < SMALL) {
      return 0d;
    }
    if (Double.isNaN(discount)) {
      discount = 1d; //ref value is returned
    }

    int sign = isCall ? 1 : -1;
    double d1 = 0d;
    double d2 = 0d;
    if (Math.abs(spot - strike) < SMALL || (spot > LARGE && strike > LARGE) || sigmaRootT > LARGE) {
      double coefD1 = Double.isNaN(Math.abs(costOfCarry) / lognormalVol) ?
          Math.signum(costOfCarry) + 0.5 * lognormalVol :
          (costOfCarry / lognormalVol + 0.5 * lognormalVol);
      double tmpD1 = Math.abs(coefD1) < SMALL ? 0d : coefD1 * rootT;
      d1 = Double.isNaN(tmpD1) ? Math.signum(coefD1) : tmpD1;
      double coefD2 = Double.isNaN(Math.abs(costOfCarry) / lognormalVol) ?
          Math.signum(costOfCarry) - 0.5 * lognormalVol :
          (costOfCarry / lognormalVol - 0.5 * lognormalVol);
      double tmpD2 = Math.abs(coefD2) < SMALL ? 0d : coefD2 * rootT;
      d2 = Double.isNaN(tmpD2) ? Math.signum(coefD2) : tmpD2;
    } else {
      if (sigmaRootT < SMALL) {
        double scnd = (Math.abs(costOfCarry) > LARGE && rootT < SMALL) ? Math.signum(costOfCarry) : costOfCarry * rootT;
        double tmp = (Math.log(spot / strike) / rootT + scnd) / lognormalVol;
        d1 = Double.isNaN(tmp) ? 0d : tmp;
        d2 = d1;
      } else {
        double tmp = costOfCarry * rootT / lognormalVol;
        double sig = (costOfCarry >= 0d) ? 1d : -1d;
        double scnd = Double.isNaN(tmp) ?
            ((lognormalVol < LARGE && lognormalVol > SMALL) ?
                sig / lognormalVol :
                sig * rootT) :
            tmp;
        double d1Tmp = Math.log(spot / strike) / sigmaRootT + scnd + 0.5 * sigmaRootT;
        double d2Tmp = Math.log(spot / strike) / sigmaRootT + scnd - 0.5 * sigmaRootT;
        d1 = Double.isNaN(d1Tmp) ? 0d : d1Tmp;
        d2 = Double.isNaN(d2Tmp) ? 0d : d2Tmp;
      }
    }
    double coefPdf = 0d;
    if (timeToExpiry < SMALL) {
      coefPdf = (Math.abs(spot - strike) < SMALL || (spot > LARGE && strike > LARGE)) ?
          1d / sigmaRootT :
          Math.log(spot / strike) / sigmaRootT / timeToExpiry;
    } else {
      double cocMod = costOfCarry / sigmaRootT;
      if (Double.isNaN(cocMod)) {
        cocMod = 1d;
      }
      double tmp = d1 / timeToExpiry;
      tmp = Double.isNaN(tmp) ? (d1 >= 0d ? 1d : -1.) : tmp;
      coefPdf = cocMod - 0.5 * tmp;
    }

    double normPdf = NORMAL.getPDF(d2);
    double normCdf = NORMAL.getCDF(sign * d2);
    double first = normPdf < SMALL ? 0d : (Double.isNaN(coefPdf) ? 0d : normPdf * coefPdf);
    double second = normCdf < SMALL ? 0d : interestRate * normCdf;
    double res = discount * (first - sign * second);

    return Double.isNaN(res) ? 0d : res;
  }

  private  BlackScholesFormulaRepository();

}