private static InstrumentDerivative[][] convert(
     final InstrumentDefinition<?>[][] definitions, final boolean withToday) {
   final InstrumentDerivative[][] instruments = new InstrumentDerivative[definitions.length][];
   for (int loopcurve = 0; loopcurve < definitions.length; loopcurve++) {
     instruments[loopcurve] = new InstrumentDerivative[definitions[loopcurve].length];
     int loopins = 0;
     for (final InstrumentDefinition<?> instrument : definitions[loopcurve]) {
       InstrumentDerivative ird;
       if (instrument instanceof SwapFixedONDefinition) {
         ird = ((SwapFixedONDefinition) instrument).toDerivative(NOW, getTSSwapFixedON(withToday));
       } else {
         if (instrument instanceof SwapFixedIborDefinition) {
           ird =
               ((SwapFixedIborDefinition) instrument)
                   .toDerivative(NOW, getTSSwapFixedIbor(withToday));
         } else {
           if (instrument instanceof SwapIborIborDefinition) {
             ird =
                 ((SwapIborIborDefinition) instrument)
                     .toDerivative(NOW, getTSSwapIborIbor(withToday));
           } else {
             ird = instrument.toDerivative(NOW);
           }
         }
       }
       instruments[loopcurve][loopins++] = ird;
     }
   }
   return instruments;
 }
 @SuppressWarnings("unchecked")
 private static InstrumentDerivative[][] convert(
     final InstrumentDefinition<?>[][] definitions, final int unit, final boolean withToday) {
   //    int nbDef = 0;
   //    for (final InstrumentDefinition<?>[] definition : definitions) {
   //      nbDef += definition.length;
   //    }
   final InstrumentDerivative[][] instruments = new InstrumentDerivative[definitions.length][];
   for (int loopcurve = 0; loopcurve < definitions.length; loopcurve++) {
     instruments[loopcurve] = new InstrumentDerivative[definitions[loopcurve].length];
     int loopins = 0;
     for (final InstrumentDefinition<?> instrument : definitions[loopcurve]) {
       InstrumentDerivative ird;
       if (instrument instanceof SwapFixedInflationZeroCouponDefinition) {
         /* ird = ((SwapFixedInflationZeroCouponDefinition) instrument).toDerivative(NOW, getTSSwapFixedInflation(withToday, unit), NOT_USED_2);*/
         final Annuity<? extends Payment> ird1 =
             ((SwapFixedInflationZeroCouponDefinition) instrument)
                 .getFirstLeg()
                 .toDerivative(NOW, NOT_USED_2);
         final Annuity<? extends Payment> ird2 =
             ((SwapFixedInflationZeroCouponDefinition) instrument)
                 .getSecondLeg()
                 .toDerivative(NOW, TS_PRICE_INDEX_USD_WITH_TODAY, NOT_USED_2);
         ird = new Swap<>(ird1, ird2);
       } else {
         ird = instrument.toDerivative(NOW, NOT_USED_2);
       }
       instruments[loopcurve][loopins++] = ird;
     }
   }
   return instruments;
 }
 @Override
 public Collection<IborIndex> visitAnnuityDefinition(
     final AnnuityDefinition<? extends PaymentDefinition> definition) {
   final Collection<IborIndex> result = new HashSet<>();
   for (final InstrumentDefinition<?> payment : definition.getPayments()) {
     result.addAll(payment.accept(this));
   }
   return result;
 }
 @Override
 public InstrumentDerivative convert(
     final Security security,
     final InstrumentDefinition<?> definition,
     final ZonedDateTime now,
     final String[] curveNames,
     final HistoricalTimeSeriesBundle timeSeries) {
   if (curveNames.length == 1) {
     final String[] singleCurve = new String[] {curveNames[0], curveNames[0]};
     return definition.toDerivative(now, singleCurve);
   }
   return definition.toDerivative(now, curveNames);
 }
 private static InstrumentDerivative convert(
     final InstrumentDefinition<?> instrument, final boolean withToday) {
   InstrumentDerivative ird;
   if (instrument instanceof SwapFixedONDefinition) {
     ird = ((SwapFixedONDefinition) instrument).toDerivative(NOW, getTSSwapFixedON(withToday));
   } else {
     ird = instrument.toDerivative(NOW);
   }
   return ird;
 }
 private static InstrumentDerivative[][] convert(final InstrumentDefinition<?>[][] definitions) {
   final InstrumentDerivative[][] instruments = new InstrumentDerivative[definitions.length][];
   for (int loopcurve = 0; loopcurve < definitions.length; loopcurve++) {
     instruments[loopcurve] = new InstrumentDerivative[definitions[loopcurve].length];
     int loopins = 0;
     for (final InstrumentDefinition<?> instrument : definitions[loopcurve]) {
       InstrumentDerivative ird;
       if (instrument instanceof SwapFixedInflationZeroCouponDefinition) {
         final Annuity<? extends Payment> ird1 =
             ((SwapFixedInflationZeroCouponDefinition) instrument).getFirstLeg().toDerivative(NOW);
         final Annuity<? extends Payment> ird2 =
             ((SwapFixedInflationZeroCouponDefinition) instrument)
                 .getSecondLeg()
                 .toDerivative(NOW, TS_PRICE_INDEX_USD_WITH_TODAY);
         ird = new Swap<>(ird1, ird2);
       } else {
         ird = instrument.toDerivative(NOW);
       }
       instruments[loopcurve][loopins++] = ird;
     }
   }
   return instruments;
 }
 private static InstrumentDerivative convert(final InstrumentDefinition<?> instrument) {
   InstrumentDerivative ird;
   if (instrument instanceof SwapFixedInflationZeroCouponDefinition) {
     final Annuity<? extends Payment> ird1 =
         ((SwapFixedInflationZeroCouponDefinition) instrument).getFirstLeg().toDerivative(NOW);
     final Annuity<? extends Payment> ird2 =
         ((SwapFixedInflationZeroCouponDefinition) instrument)
             .getSecondLeg()
             .toDerivative(NOW, TS_PRICE_INDEX_USD_WITH_TODAY);
     ird = new Swap<>(ird1, ird2);
   } else {
     ird = instrument.toDerivative(NOW);
   }
   return ird;
 }
 @Override
 public Set<ComputedValue> execute(
     final FunctionExecutionContext executionContext,
     final FunctionInputs inputs,
     final ComputationTarget target,
     final Set<ValueRequirement> desiredValues) {
   final Clock snapshotClock = executionContext.getValuationClock();
   final ZonedDateTime now = snapshotClock.zonedDateTime();
   final FinancialSecurity security = (FinancialSecurity) target.getSecurity();
   final InstrumentDefinition<InstrumentDerivative> definition =
       (InstrumentDefinition<InstrumentDerivative>) security.accept(VISITOR);
   final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor());
   final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor());
   final ValueRequirement desiredValue = desiredValues.iterator().next();
   final String putCurveName = desiredValue.getConstraint(PROPERTY_PUT_CURVE);
   final String callCurveName = desiredValue.getConstraint(PROPERTY_CALL_CURVE);
   final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE);
   final String putForwardCurveName = desiredValue.getConstraint(PROPERTY_PUT_FORWARD_CURVE);
   final String callForwardCurveName = desiredValue.getConstraint(PROPERTY_CALL_FORWARD_CURVE);
   final String putCurveCalculationMethod =
       desiredValue.getConstraint(PROPERTY_PUT_CURVE_CALCULATION_METHOD);
   final String callCurveCalculationMethod =
       desiredValue.getConstraint(PROPERTY_CALL_CURVE_CALCULATION_METHOD);
   final String interpolatorName =
       desiredValue.getConstraint(InterpolatedDataProperties.X_INTERPOLATOR_NAME);
   final String leftExtrapolatorName =
       desiredValue.getConstraint(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME);
   final String rightExtrapolatorName =
       desiredValue.getConstraint(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME);
   final String spread = desiredValue.getConstraint(PROPERTY_CALL_SPREAD_VALUE);
   final double spreadValue = Double.parseDouble(spread);
   final String fullPutCurveName = putCurveName + "_" + putCurrency.getCode();
   final String fullCallCurveName = callCurveName + "_" + callCurrency.getCode();
   final String[] curveNames;
   if (FXUtils.isInBaseQuoteOrder(
       putCurrency, callCurrency)) { // To get Base/quote in market standard order.
     curveNames = new String[] {fullPutCurveName, fullCallCurveName};
   } else {
     curveNames = new String[] {fullCallCurveName, fullPutCurveName};
   }
   final YieldAndDiscountCurve putFundingCurve = getCurve(inputs, putCurrency, putCurveName);
   final YieldAndDiscountCurve callFundingCurve = getCurve(inputs, callCurrency, callCurveName);
   final YieldAndDiscountCurve[] curves;
   final Map<String, Currency> curveCurrency = new HashMap<String, Currency>();
   curveCurrency.put(fullPutCurveName, putCurrency);
   curveCurrency.put(fullCallCurveName, callCurrency);
   final String[] allCurveNames;
   final Currency ccy1;
   final Currency ccy2;
   if (FXUtils.isInBaseQuoteOrder(
       putCurrency, callCurrency)) { // To get Base/quote in market standard order.
     ccy1 = putCurrency;
     ccy2 = callCurrency;
     curves = new YieldAndDiscountCurve[] {putFundingCurve, callFundingCurve};
     allCurveNames = new String[] {fullPutCurveName, fullCallCurveName};
   } else {
     curves = new YieldAndDiscountCurve[] {callFundingCurve, putFundingCurve};
     allCurveNames = new String[] {fullCallCurveName, fullPutCurveName};
     ccy1 = callCurrency;
     ccy2 = putCurrency;
   }
   final InstrumentDerivative fxOption = definition.toDerivative(now, curveNames);
   final YieldCurveBundle yieldCurves = new YieldCurveBundle(allCurveNames, curves);
   final Object spotObject = inputs.getValue(ValueRequirementNames.SPOT_RATE);
   if (spotObject == null) {
     throw new OpenGammaRuntimeException("Could not get spot rate");
   }
   final double spot = (Double) spotObject;
   final ValueRequirement fxVolatilitySurfaceRequirement =
       getSurfaceRequirement(
           surfaceName,
           putCurrency,
           callCurrency,
           interpolatorName,
           leftExtrapolatorName,
           rightExtrapolatorName);
   final Object volatilitySurfaceObject = inputs.getValue(fxVolatilitySurfaceRequirement);
   if (volatilitySurfaceObject == null) {
     throw new OpenGammaRuntimeException("Could not get " + fxVolatilitySurfaceRequirement);
   }
   final SmileDeltaTermStructureParametersStrikeInterpolation smiles =
       (SmileDeltaTermStructureParametersStrikeInterpolation) volatilitySurfaceObject;
   final FXMatrix fxMatrix = new FXMatrix(ccy1, ccy2, spot);
   final ValueProperties.Builder properties =
       getResultProperties(
           putCurveName,
           putForwardCurveName,
           putCurveCalculationMethod,
           callCurveName,
           callForwardCurveName,
           callCurveCalculationMethod,
           surfaceName,
           spread,
           interpolatorName,
           leftExtrapolatorName,
           rightExtrapolatorName,
           target);
   final ValueSpecification spec =
       new ValueSpecification(_valueRequirementName, target.toSpecification(), properties.get());
   final YieldCurveBundle curvesWithFX =
       new YieldCurveBundle(fxMatrix, curveCurrency, yieldCurves.getCurvesMap());
   final SmileDeltaTermStructureDataBundle smileBundle =
       new SmileDeltaTermStructureDataBundle(curvesWithFX, smiles, Pair.of(ccy1, ccy2));
   return getResult(fxOption, spreadValue, smileBundle, spec);
 }
 @Override
 public Set<ComputedValue> execute(
     final FunctionExecutionContext executionContext,
     final FunctionInputs inputs,
     final ComputationTarget target,
     final Set<ValueRequirement> desiredValues) {
   final Clock snapshotClock = executionContext.getValuationClock();
   final ZonedDateTime now = snapshotClock.zonedDateTime();
   final SecuritySource securitySource =
       OpenGammaExecutionContext.getSecuritySource(executionContext);
   final SwaptionSecurity security = (SwaptionSecurity) target.getSecurity();
   final ValueRequirement desiredValue = desiredValues.iterator().next();
   final Currency currency = FinancialSecurityUtils.getCurrency(security);
   final String forwardCurveName =
       desiredValue.getConstraint(YieldCurveFunction.PROPERTY_FORWARD_CURVE);
   final String fundingCurveName =
       desiredValue.getConstraint(YieldCurveFunction.PROPERTY_FUNDING_CURVE);
   final String curveCalculationMethod =
       desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_METHOD);
   final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE);
   final Object forwardCurveObject =
       inputs.getValue(
           YieldCurveFunction.getCurveRequirement(
               currency,
               forwardCurveName,
               forwardCurveName,
               fundingCurveName,
               curveCalculationMethod));
   if (forwardCurveObject == null) {
     throw new OpenGammaRuntimeException("Could not get forward curve");
   }
   final Object fundingCurveObject =
       inputs.getValue(
           YieldCurveFunction.getCurveRequirement(
               currency,
               fundingCurveName,
               forwardCurveName,
               fundingCurveName,
               curveCalculationMethod));
   if (fundingCurveObject == null) {
     throw new OpenGammaRuntimeException("Could not get funding curve");
   }
   final Object volatilitySurfaceObject =
       inputs.getValue(getVolatilityRequirement(surfaceName, currency));
   if (volatilitySurfaceObject == null) {
     throw new OpenGammaRuntimeException("Could not get volatility surface");
   }
   final VolatilitySurface volatilitySurface = (VolatilitySurface) volatilitySurfaceObject;
   if (!(volatilitySurface.getSurface() instanceof InterpolatedDoublesSurface)) {
     throw new OpenGammaRuntimeException(
         "Expecting an InterpolatedDoublesSurface; got "
             + volatilitySurface.getSurface().getClass());
   }
   final YieldAndDiscountCurve forwardCurve = (YieldAndDiscountCurve) forwardCurveObject;
   final YieldAndDiscountCurve fundingCurve = (YieldAndDiscountCurve) fundingCurveObject;
   final InstrumentDefinition<?> definition = security.accept(_visitor);
   final InstrumentDerivative swaption =
       definition.toDerivative(now, new String[] {fundingCurveName, forwardCurveName});
   final ValueProperties properties =
       getResultProperties(
           currency.getCode(),
           forwardCurveName,
           fundingCurveName,
           curveCalculationMethod,
           surfaceName);
   final ValueSpecification spec =
       new ValueSpecification(_valueRequirementName, target.toSpecification(), properties);
   final YieldCurveBundle curves =
       new YieldCurveBundle(
           new String[] {fundingCurveName, forwardCurveName},
           new YieldAndDiscountCurve[] {fundingCurve, forwardCurve});
   final BlackSwaptionParameters parameters =
       new BlackSwaptionParameters(
           volatilitySurface.getSurface(),
           SwaptionUtils.getSwapGenerator(security, definition, securitySource));
   final YieldCurveWithBlackSwaptionBundle data =
       new YieldCurveWithBlackSwaptionBundle(parameters, curves);
   return getResult(swaption, data, spec);
 }