@Override
    protected void buildMessage(
        final FudgeSerializer serializer,
        final MutableFudgeMsg message,
        final CurrencyLabelledMatrix1D object) {
      final MutableFudgeMsg msg = serializer.newMessage();

      final Currency[] keys = object.getKeys();
      final Object[] labels = object.getLabels();
      final double[] values = object.getValues();
      for (int i = 0; i < object.size(); i++) {
        msg.add(LABEL_TYPE_ORDINAL, labels[i].getClass().getName());
        msg.add(KEY_ORDINAL, keys[i]);
        serializer.addToMessage(msg, null, LABEL_ORDINAL, labels[i]);
        msg.add(VALUE_ORDINAL, values[i]);
      }

      message.add(MATRIX_FIELD_NAME, msg);
    }
 @Override
 public Set<ComputedValue> execute(
     final FunctionExecutionContext executionContext,
     final FunctionInputs inputs,
     final ComputationTarget target,
     final Set<ValueRequirement> desiredValues) {
   final ComputedValue input = inputs.getAllValues().iterator().next();
   final Object value = input.getValue();
   final ValueSpecification specification =
       new ValueSpecification(
           _requirementName,
           target.toSpecification(),
           getResultProperties(input.getSpecification()));
   ComputedValue scaledValue = null;
   if (value instanceof Double) {
     Double doubleValue = (Double) value;
     final double quantity = target.getPosition().getQuantity().doubleValue();
     doubleValue *= quantity;
     scaledValue = new ComputedValue(specification, doubleValue);
   } else if (value instanceof YieldCurveNodeSensitivityDataBundle) {
     final YieldCurveNodeSensitivityDataBundle nodeSensitivities =
         (YieldCurveNodeSensitivityDataBundle) value;
     final double quantity = target.getPosition().getQuantity().doubleValue();
     final Currency ccy = nodeSensitivities.getCurrency();
     final String name = nodeSensitivities.getYieldCurveName();
     final DoubleLabelledMatrix1D m = nodeSensitivities.getLabelledMatrix();
     final double[] scaled = getScaledMatrix(m.getValues(), quantity);
     scaledValue =
         new ComputedValue(
             specification,
             new YieldCurveNodeSensitivityDataBundle(
                 ccy, new DoubleLabelledMatrix1D(m.getKeys(), m.getLabels(), scaled), name));
   } else if (value instanceof DoubleLabelledMatrix1D) {
     final DoubleLabelledMatrix1D m = (DoubleLabelledMatrix1D) value;
     final double quantity = target.getPosition().getQuantity().doubleValue();
     final double[] scaled = getScaledMatrix(m.getValues(), quantity);
     scaledValue =
         new ComputedValue(
             specification, new DoubleLabelledMatrix1D(m.getKeys(), m.getLabels(), scaled));
   } else if (value instanceof LocalDateLabelledMatrix1D) {
     final LocalDateLabelledMatrix1D m = (LocalDateLabelledMatrix1D) value;
     final double quantity = target.getPosition().getQuantity().doubleValue();
     final double[] scaled = getScaledMatrix(m.getValues(), quantity);
     scaledValue =
         new ComputedValue(
             specification, new LocalDateLabelledMatrix1D(m.getKeys(), m.getLabels(), scaled));
   } else if (value instanceof ZonedDateTimeLabelledMatrix1D) {
     final ZonedDateTimeLabelledMatrix1D m = (ZonedDateTimeLabelledMatrix1D) value;
     final double quantity = target.getPosition().getQuantity().doubleValue();
     final double[] scaled = getScaledMatrix(m.getValues(), quantity);
     scaledValue =
         new ComputedValue(
             specification, new ZonedDateTimeLabelledMatrix1D(m.getKeys(), m.getLabels(), scaled));
   } else if (value instanceof CurrencyLabelledMatrix1D) {
     final CurrencyLabelledMatrix1D m = (CurrencyLabelledMatrix1D) value;
     final double quantity = target.getPosition().getQuantity().doubleValue();
     final double[] scaled = getScaledMatrix(m.getValues(), quantity);
     scaledValue =
         new ComputedValue(
             specification, new CurrencyLabelledMatrix1D(m.getKeys(), m.getLabels(), scaled));
   } else if (value instanceof StringLabelledMatrix1D) {
     final StringLabelledMatrix1D m = (StringLabelledMatrix1D) value;
     final double quantity = target.getPosition().getQuantity().doubleValue();
     final double[] scaled = getScaledMatrix(m.getValues(), quantity);
     scaledValue =
         new ComputedValue(specification, new StringLabelledMatrix1D(m.getKeys(), scaled));
   } else if (_requirementName.equals(
       ValueRequirementNames
           .PRESENT_VALUE_CURVE_SENSITIVITY)) { // TODO this should probably not be done like this
     @SuppressWarnings("unchecked")
     final Map<String, List<DoublesPair>> map = (Map<String, List<DoublesPair>>) value;
     final Map<String, List<DoublesPair>> scaled = new HashMap<String, List<DoublesPair>>();
     for (final Map.Entry<String, List<DoublesPair>> entry : map.entrySet()) {
       final List<DoublesPair> scaledList = new ArrayList<DoublesPair>();
       for (final DoublesPair pair : entry.getValue()) {
         scaledList.add(
             DoublesPair.of(
                 pair.first, pair.second * target.getPosition().getQuantity().doubleValue()));
       }
       scaled.put(entry.getKey(), scaledList);
     }
     scaledValue = new ComputedValue(specification, scaled);
   } else if (value instanceof DoubleLabelledMatrix2D) {
     final DoubleLabelledMatrix2D matrix = (DoubleLabelledMatrix2D) value;
     final Double[] xKeys = matrix.getXKeys();
     final Object[] xLabels = matrix.getXLabels();
     final Double[] yKeys = matrix.getYKeys();
     final Object[] yLabels = matrix.getYLabels();
     final double[][] values = matrix.getValues();
     final int n = values.length;
     final int m = values[0].length;
     final double[][] scaledValues = new double[n][m];
     final double scale = target.getPosition().getQuantity().doubleValue();
     for (int i = 0; i < n; i++) {
       for (int j = 0; j < m; j++) {
         scaledValues[i][j] = values[i][j] * scale;
       }
     }
     scaledValue =
         new ComputedValue(
             specification,
             new DoubleLabelledMatrix2D(xKeys, xLabels, yKeys, yLabels, scaledValues));
   } else if (value instanceof DoubleLabelledMatrix3D) {
     final DoubleLabelledMatrix3D matrix = (DoubleLabelledMatrix3D) value;
     final Double[] xKeys = matrix.getXKeys();
     final Object[] xLabels = matrix.getXLabels();
     final Double[] yKeys = matrix.getYKeys();
     final Object[] yLabels = matrix.getYLabels();
     final Double[] zKeys = matrix.getZKeys();
     final Object[] zLabels = matrix.getZLabels();
     final double[][][] values = matrix.getValues();
     final int n = values.length;
     final int m = values[0].length;
     final int l = values[0][0].length;
     final double[][][] scaledValues = new double[n][m][l];
     final double scale = target.getPosition().getQuantity().doubleValue();
     for (int i = 0; i < n; i++) {
       for (int j = 0; j < m; j++) {
         for (int k = 0; k < l; k++) {
           scaledValues[i][j][k] = values[i][j][k] * scale;
         }
       }
     }
     scaledValue =
         new ComputedValue(
             specification,
             new DoubleLabelledMatrix3D(
                 xKeys, xLabels, yKeys, yLabels, zKeys, zLabels, scaledValues));
   } else {
     // REVIEW emcleod 27-1-2011 aaaaaaaaaarrrrrrrrgggggghhhhhhhhh Why is nothing done here?
     scaledValue = new ComputedValue(specification, value);
   }
   return Collections.singleton(scaledValue);
 }