@Override
  public Set<ValueSpecification> getResults(
      final FunctionCompilationContext context,
      final ComputationTarget target,
      final Map<ValueSpecification, ValueRequirement> inputs) {
    if (inputs.size() == 1) {
      ValueSpecification input = inputs.keySet().iterator().next();
      if (getValueRequirementName().equals(input.getValueName())) {
        return inputs.keySet();
      }
    }
    ValueSpecification superSpec = super.getResults(context, target, inputs).iterator().next();
    Builder properties =
        superSpec
            .getProperties()
            .copy()
            .withAny(s_priceShift)
            .withAny(s_volShift)
            .withAny(s_priceShiftType)
            .withAny(s_volShiftType);

    return Collections.singleton(
        new ValueSpecification(
            getValueRequirementName(), target.toSpecification(), properties.get()));
  }
 protected void encodeMarketDataAliases(
     final FudgeSerializer serializer,
     final MutableFudgeMsg msg,
     final Map<ValueSpecification, Collection<ValueSpecification>> marketDataEntries) {
   final MutableFudgeMsg msgRequirements = msg.addSubMessage(MARKET_DATA_REQUIREMENTS_FIELD, null);
   final MutableFudgeMsg msgAliases = msg.addSubMessage(MARKET_DATA_ALIASES_FIELD, null);
   for (final Map.Entry<ValueSpecification, Collection<ValueSpecification>> requirement :
       marketDataEntries.entrySet()) {
     final ValueSpecification marketData = requirement.getKey();
     serializer.addToMessage(msgRequirements, null, null, marketData);
     if (requirement.getValue().size() == 1) {
       final ValueSpecification alias = requirement.getValue().iterator().next();
       if (alias.equals(marketData)) {
         msgAliases.add(null, null, IndicatorType.INSTANCE);
       } else {
         serializer.addToMessage(msgAliases, null, null, alias);
       }
     } else {
       final MutableFudgeMsg aliases = msgAliases.addSubMessage(null, null);
       aliases.add(null, 0, "list");
       for (ValueSpecification alias : requirement.getValue()) {
         if (alias.equals(marketData)) {
           msgAliases.add(null, null, IndicatorType.INSTANCE);
         } else {
           serializer.addToMessage(aliases, null, null, alias);
         }
       }
     }
   }
 }
 @Override
 public Set<ValueSpecification> getResults(
     final FunctionCompilationContext context,
     final ComputationTarget target,
     final Map<ValueSpecification, ValueRequirement> inputs) {
   if (inputs.size() == 1) {
     final ValueSpecification input = Iterables.getOnlyElement(inputs.keySet());
     if (ValueRequirementNames.PNL_SERIES.equals(input.getValueName())) {
       return Collections.singleton(input);
     }
   }
   final FXForwardSecurity security = (FXForwardSecurity) target.getPosition().getSecurity();
   final CurrencyPair currencyPair =
       _currencyPairs.getCurrencyPair(security.getPayCurrency(), security.getReceiveCurrency());
   if (currencyPair == null) {
     return null;
   }
   final Currency currencyBase = currencyPair.getBase();
   String resultCurrency = null;
   final ValueProperties.Builder builder = createValueProperties();
   for (final Map.Entry<ValueSpecification, ValueRequirement> entry : inputs.entrySet()) {
     final ValueSpecification inputSpec = entry.getKey();
     final ValueRequirement inputReq = entry.getValue();
     if (inputReq.getValueName().equals(RETURN_SERIES)) {
       final Set<String> resultCurrencies = inputReq.getConstraints().getValues(CURRENCY);
       if (resultCurrencies != null && resultCurrencies.size() == 1) {
         resultCurrency = inputReq.getConstraint(CURRENCY);
       } else {
         resultCurrency = currencyBase.getCode();
       }
     }
     for (final String propertyName : inputSpec.getProperties().getProperties()) {
       if (ValuePropertyNames.FUNCTION.equals(propertyName)) {
         continue;
       }
       final Set<String> values = inputSpec.getProperties().getValues(propertyName);
       if (values == null || values.isEmpty()) {
         builder.withAny(propertyName);
       } else {
         builder.with(propertyName, values);
       }
     }
   }
   if (resultCurrency == null) {
     return null;
   }
   builder
       .with(ValuePropertyNames.CURRENCY, resultCurrency)
       .with(
           ValuePropertyNames.PROPERTY_PNL_CONTRIBUTIONS,
           ValueRequirementNames.FX_CURRENCY_EXPOSURE);
   return ImmutableSet.of(
       new ValueSpecification(
           ValueRequirementNames.PNL_SERIES, target.toSpecification(), builder.get()));
 }
 protected ValueSpecification getOutputSpec(ValueSpecification inputSpec) {
   ValueProperties outputProperties =
       inputSpec
           .getProperties()
           .copy()
           .withoutAny(ValuePropertyNames.FUNCTION)
           .with(ValuePropertyNames.FUNCTION, getUniqueId())
           .get();
   return new ValueSpecification(
       ValueRequirementNames.TARGET, inputSpec.getTargetSpecification(), outputProperties);
 }
 /**
  * Simplifies the type based on the associated {@link ComputationTargetResolver}.
  *
  * @param valueSpec the specification to process, not null
  * @return the possibly simplified specification, not null
  */
 public ValueSpecification simplifyType(final ValueSpecification valueSpec) {
   final ComputationTargetSpecification oldTargetSpec = valueSpec.getTargetSpecification();
   final ComputationTargetSpecification newTargetSpec =
       ComputationTargetResolverUtils.simplifyType(
           oldTargetSpec, getCompilationContext().getComputationTargetResolver());
   if (newTargetSpec == oldTargetSpec) {
     return MemoryUtils.instance(valueSpec);
   } else {
     return MemoryUtils.instance(
         new ValueSpecification(
             valueSpec.getValueName(), newTargetSpec, valueSpec.getProperties()));
   }
 }
 /**
  * Tests if this requirement can be satisfied by a given value specification.
  *
  * <p>A {@link ValueSpecification} can satisfy a requirement if both of the following are true:
  *
  * <ul>
  *   <li>it is for the same value on the same computation target
  *   <li>the properties associated with the value satisfy the constraints on the requirement
  * </ul>
  *
  * @param valueSpecification the value specification to test, not null
  * @return {@code true} if this requirement is satisfied by the specification, {@code false}
  *     otherwise.
  */
 public boolean isSatisfiedBy(final ValueSpecification valueSpecification) {
   // value names are interned by this and specifications
   if (getValueName() != valueSpecification.getValueName()) {
     return false;
   }
   if (!getTargetSpecification().equals(getTargetSpecification())) {
     return false;
   }
   if (!getConstraints().isSatisfiedBy(valueSpecification.getProperties())) {
     return false;
   }
   return true;
 }
 private static VolatilitySurfaceKey createKey(ValueSpecification valueSpecification) {
   UniqueId uniqueId = valueSpecification.getTargetSpecification().getUniqueId();
   String surface = valueSpecification.getProperties().getStrictValue(ValuePropertyNames.SURFACE);
   String instrumentType = valueSpecification.getProperties().getStrictValue("InstrumentType");
   String quoteType =
       valueSpecification
           .getProperties()
           .getStrictValue(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_QUOTE_TYPE);
   String quoteUnits =
       valueSpecification
           .getProperties()
           .getStrictValue(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_UNITS);
   return VolatilitySurfaceKey.of(uniqueId, surface, instrumentType, quoteType, quoteUnits);
 }
 @Override
 public Set<ValueSpecification> getResults(
     final FunctionCompilationContext context,
     final ComputationTarget target,
     final Map<ValueSpecification, ValueRequirement> inputs) {
   ValueSpecification inputValue = null;
   ValueSpecification inputParent = null;
   final UniqueId value = target.getUniqueId();
   for (ValueSpecification input : inputs.keySet()) {
     if (value.equals(input.getTargetSpecification().getUniqueId())) {
       assert inputValue == null;
       inputValue = input;
     } else {
       assert inputParent == null;
       inputParent = input;
     }
   }
   final ValueProperties rawResultProperties =
       inputValue.getProperties().intersect(inputParent.getProperties());
   final ValueProperties.Builder resultPropertiesBuilder = rawResultProperties.copy();
   for (String unit : UnitProperties.unitPropertyNames()) {
     final Set<String> valueUnits = inputValue.getProperties().getValues(unit);
     final Set<String> parentUnits = inputParent.getProperties().getValues(unit);
     if (valueUnits != null) {
       if (parentUnits != null) {
         if (rawResultProperties.getValues(unit) != null) {
           // The operation is a division, so there are no units on the result
           resultPropertiesBuilder.withoutAny(unit);
         } else {
           // No common intersection between parent and value properties for this unit
           return null;
         }
       } else {
         // Parent did not include the same units as the value
         return null;
       }
     } else {
       if (parentUnits != null) {
         // Value did not include the same units as the parent
         return null;
       }
     }
   }
   resultPropertiesBuilder
       .withoutAny(VALUE_PROPERTY_NAME)
       .with(VALUE_PROPERTY_NAME, inputValue.getValueName());
   resultPropertiesBuilder
       .withoutAny(ValuePropertyNames.FUNCTION)
       .with(ValuePropertyNames.FUNCTION, getUniqueId());
   return Collections.singleton(
       new ValueSpecification(
           ValueRequirementNames.WEIGHT, target.toSpecification(), resultPropertiesBuilder.get()));
 }
 /**
  * Indicates whether an output with the given specification should be included in the results.
  *
  * @param outputSpecification the specification of the output value, not null
  * @param dependencyGraph the dependency graph to which the output value belongs, not null
  * @return true if the output value should be included in the results
  */
 public boolean shouldOutputResult(
     ValueSpecification outputSpecification, DependencyGraph dependencyGraph) {
   ArgumentChecker.notNull(outputSpecification, "outputSpecification");
   ArgumentChecker.notNull(dependencyGraph, "dependencyGraph");
   ComputationTargetType targetType = outputSpecification.getTargetSpecification().getType();
   return getOutputMode(targetType).shouldOutputResult(outputSpecification, dependencyGraph);
 }
 @Override
 public DistinctMarketDataSelector findMatchingSelector(
     ValueSpecification valueSpecification,
     String calculationConfigurationName,
     SelectorResolver resolver) {
   if (_calcConfigNames != null && !_calcConfigNames.contains(calculationConfigurationName)) {
     return null;
   }
   if (!s_compatibleVRNames.contains(valueSpecification.getValueName())) {
     return null;
   }
   VolatilitySurfaceKey key = createKey(valueSpecification);
   if (!contains(_names, key.getName())) {
     return null;
   }
   if (_nameMatchPattern != null
       && !_nameMatchPattern.getPattern().matcher(key.getName()).matches()) {
     return null;
   }
   if (_nameLikePattern != null
       && !_nameLikePattern.getPattern().matcher(key.getName()).matches()) {
     return null;
   }
   if (!contains(_instrumentTypes, key.getInstrumentType())) {
     return null;
   }
   if (!contains(_quoteTypes, key.getQuoteType())) {
     return null;
   }
   if (!contains(_quoteUnits, key.getQuoteUnits())) {
     return null;
   }
   return this;
 }
 @Override
 public String toString() {
   // carefully select useful fields for toString
   ToStringStyle style = ToStringStyle.SHORT_PREFIX_STYLE;
   StringBuffer sb = new StringBuffer();
   style.appendStart(sb, this);
   style.append(sb, "result", getInvocationResult(), null);
   ValueSpecification spec = getSpecification();
   if (spec != null) {
     style.append(sb, "name", spec.getValueName(), null);
     ComputationTargetSpecification targetSpec = spec.getTargetSpecification();
     style.append(sb, "targetId", targetSpec.getIdentifier(), null);
     style.append(sb, "targetType", targetSpec.getType(), null);
     style.append(sb, "properties", spec.getProperties(), null);
   }
   style.append(sb, "value", getValue(), null);
   style.appendEnd(sb, this);
   return sb.toString();
 }
 private static DoubleValueFormatter getFormatter(ValueSpecification valueSpec) {
   if (valueSpec == null) {
     return s_defaultFormatter;
   }
   DoubleValueFormatter valueNameFormatter = s_formatters.get(valueSpec.getValueName());
   if (valueNameFormatter != null) {
     return valueNameFormatter;
   } else {
     return s_defaultFormatter;
   }
 }
 @Override
 public int hashCode() {
   int result = _specification.hashCode();
   result = 31 * result + (_value != null ? _value.hashCode() : 0);
   result = 31 * result + (_result != null ? _result.hashCode() : 0);
   result = 31 * result + (_exceptionClass != null ? _exceptionClass.hashCode() : 0);
   result = 31 * result + (_exceptionMsg != null ? _exceptionMsg.hashCode() : 0);
   result = 31 * result + (_stackTrace != null ? _stackTrace.hashCode() : 0);
   result = 31 * result + (_missingInputs != null ? _missingInputs.hashCode() : 0);
   result = 31 * result + (_originalRequirements != null ? _originalRequirements.hashCode() : 0);
   return result;
 }
 // Note that the properties are created using createValueProperties() - this sets the name of the
 // function in the properties.
 // Not using this means that this function will not work
 private ValueSpecification getValueSpecification(final EquityVarianceSwapSecurity security) {
   final ValueProperties properties =
       createValueProperties()
           .with(ValuePropertyNames.CURRENCY, security.getCurrency().getCode())
           .withAny(ValuePropertyNames.CURVE_CALCULATION_CONFIG)
           .withAny(ValuePropertyNames.CURVE)
           .with(FORWARD_CALCULATION_METHOD, FORWARD_FROM_SPOT_AND_YIELD_CURVE)
           .get();
   return ValueSpecification.of(
       ValueRequirementNames.FORWARD,
       ComputationTargetType.SECURITY,
       security.getUniqueId(),
       properties);
 }
 @Override
 public String formatCell(BigDecimal value, ValueSpecification valueSpec) {
   DoubleValueFormatter formatter = getFormatter(valueSpec);
   String formattedNumber = formatter.format(value);
   String formattedValue;
   if (formatter.isCurrencyAmount()) {
     Set<String> currencyValues = valueSpec.getProperties().getValues(ValuePropertyNames.CURRENCY);
     String ccy;
     if (currencyValues == null) {
       formattedValue = formattedNumber;
     } else if (currencyValues.isEmpty()) {
       formattedValue = formattedNumber;
     } else {
       ccy = currencyValues.iterator().next();
       formattedValue = ccy + " " + formattedNumber;
     }
   } else {
     formattedValue = formattedNumber;
   }
   return formattedValue;
 }
 @Override
 protected Set<ComputedValue> getResult(
     final FunctionInputs inputs,
     final BondCapitalIndexedTransaction<?> bond,
     final InflationIssuerProviderInterface provider,
     final double cleanPrice,
     final ValueSpecification spec) {
   final String expectedCurrency = spec.getProperty(CURRENCY);
   final MultipleCurrencyAmount pvBond =
       CALCULATOR.presentValueFromCleanRealPrice(bond.getBondTransaction(), provider, cleanPrice);
   final MultipleCurrencyAmount pvSettlement =
       bond.getBondTransaction()
           .getSettlement()
           .accept(PVIC, provider.getInflationProvider())
           .multipliedBy(
               bond.getQuantity()
                   * bond.getBondTransaction().getCoupon().getNthPayment(0).getNotional());
   final MultipleCurrencyAmount pv = pvBond.plus(pvSettlement);
   if (pv.size() != 1
       || !(expectedCurrency.equals(pv.getCurrencyAmounts()[0].getCurrency().getCode()))) {
     throw new OpenGammaRuntimeException("Expecting a single result in " + expectedCurrency);
   }
   return Collections.singleton(new ComputedValue(spec, pv.getCurrencyAmounts()[0].getAmount()));
 }
 @Override
 public Set<ValueSpecification> getResults(
     final FunctionCompilationContext context,
     final ComputationTarget target,
     final Map<ValueSpecification, ValueRequirement> inputs) {
   String currencyPairConfigName = null;
   String payCurveName = null;
   String payCurveCalculationConfig = null;
   String receiveCurveName = null;
   String receiveCurveCalculationConfig = null;
   String daysForward = null;
   for (final Map.Entry<ValueSpecification, ValueRequirement> entry : inputs.entrySet()) {
     final ValueSpecification specification = entry.getKey();
     final ValueRequirement requirement = entry.getValue();
     if (specification.getValueName().equals(ValueRequirementNames.CURRENCY_PAIRS)) {
       currencyPairConfigName =
           specification.getProperty(CurrencyPairsFunction.CURRENCY_PAIRS_NAME);
       daysForward = requirement.getConstraint(PROPERTY_DAYS_TO_MOVE_FORWARD);
     } else if (requirement.getValueName().equals(ValueRequirementNames.YIELD_CURVE)) {
       final ValueProperties constraints = requirement.getConstraints();
       if (constraints.getProperties().contains(ValuePropertyNames.PAY_CURVE)) {
         payCurveName = Iterables.getOnlyElement(constraints.getValues(ValuePropertyNames.CURVE));
         payCurveCalculationConfig =
             Iterables.getOnlyElement(
                 constraints.getValues(ValuePropertyNames.CURVE_CALCULATION_CONFIG));
       } else if (constraints.getProperties().contains(ValuePropertyNames.RECEIVE_CURVE)) {
         receiveCurveName =
             Iterables.getOnlyElement(constraints.getValues(ValuePropertyNames.CURVE));
         receiveCurveCalculationConfig =
             Iterables.getOnlyElement(
                 constraints.getValues(ValuePropertyNames.CURVE_CALCULATION_CONFIG));
       }
     }
   }
   assert currencyPairConfigName != null;
   final CurrencyPairs baseQuotePairs =
       OpenGammaCompilationContext.getCurrencyPairsSource(context)
           .getCurrencyPairs(currencyPairConfigName);
   final FinancialSecurity security = (FinancialSecurity) target.getSecurity();
   final Currency payCurrency = security.accept(ForexVisitors.getPayCurrencyVisitor());
   final Currency receiveCurrency = security.accept(ForexVisitors.getReceiveCurrencyVisitor());
   final CurrencyPair baseQuotePair = baseQuotePairs.getCurrencyPair(payCurrency, receiveCurrency);
   if (baseQuotePair == null) {
     s_logger.error(
         "Could not get base/quote pair for currency pair ("
             + payCurrency
             + ", "
             + receiveCurrency
             + ")");
     return null;
   }
   final ValueSpecification resultSpec =
       new ValueSpecification(
           getValueRequirementName(),
           target.toSpecification(),
           getResultProperties(
                   target,
                   payCurveName,
                   receiveCurveName,
                   payCurveCalculationConfig,
                   receiveCurveCalculationConfig,
                   baseQuotePair,
                   daysForward)
               .get());
   return Collections.singleton(resultSpec);
 }