public final class ServiceInvoker implements AutoCloseable {

  /**
   * The URL of the service.
   */
  public static final HttpUrl SERVICE_URL = HttpUrl.parse("https://api.opengamma.com");
  /**
   * JSON media type.
   */
  public static final MediaType MEDIA_JSON = MediaType.parse("application/json");
  /**
   * Form media type.
   */
  public static final MediaType MEDIA_FORM = MediaType.parse("application/x-www-form-urlencoded");

  /** URL to call. */
  private final HttpUrl serviceUrl;
  /** HTTP client. */
  private final OkHttpClient httpClient;
  /** Executor. */
  private final ScheduledExecutorService executor;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance for the specified credentials.
   * <p>
   * The executor will be initialized with {@link Runtime#availableProcessors()} threads.
   * <p>
   * The invoker is {@link AutoCloseable}, thus this method should typically
   * be called as part of a try-with-resources statement.
   *
   * @param credentials  the credentials to use for authentication
   * @return the invoker
   */
  public static ServiceInvoker of(Credentials credentials) {
    return builder(credentials).build();
  }

  /**
   * Returns a builder that can be used to create an instance of the invoker.
   * <p>
   * The invoker is {@link AutoCloseable}, thus the {@code build()} method should
   * typically be called as part of a try-with-resources statement.
   *
   * @param credentials  the credentials to use for authentication
   * @return the builder, used to further customize the invoker
   */
  public static ServiceInvokerBuilder builder(Credentials credentials) {
    return new ServiceInvokerBuilder(credentials);
  }

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance for the specified credentials and URL.
   * <p>
   * The executor will be initialized with {@link Runtime#availableProcessors()} threads.
   *
   * @param credentials  the credentials to use for authentication
   * @param serviceUrl  the URL of the service
   * @return the invoker
   * @deprecated Use the builder for greater clarity and flexibility
   */
  @Deprecated
  public static ServiceInvoker of(Credentials credentials, HttpUrl serviceUrl) {
    return new ServiceInvokerBuilder(credentials)
        .serviceUrl(serviceUrl)
        .build();
  }

  /**
   * Obtains an instance for the specified credentials and executor service.
   *
   * @param credentials  the credentials to use for authentication
   * @param executor  the executor service
   * @return the invoker
   * @deprecated Use the builder for greater clarity and flexibility
   */
  @Deprecated
  public static ServiceInvoker of(Credentials credentials, ScheduledExecutorService executor) {
    return new ServiceInvokerBuilder(credentials)
        .executorService(executor)
        .build();
  }

  /**
   * Obtains an instance for the specified credentials, URL and executor service.
   *
   * @param credentials  the credentials to use for authentication
   * @param serviceUrl  the URL of the service
   * @param executor  the executor service
   * @return the invoker
   * @deprecated Use the builder for greater clarity and flexibility
   */
  @Deprecated
  public static ServiceInvoker of(Credentials credentials, HttpUrl serviceUrl, ScheduledExecutorService executor) {
    return new ServiceInvokerBuilder(credentials)
        .serviceUrl(serviceUrl)
        .executorService(executor)
        .build();
  }

  /**
   * Obtains an instance for the specified credentials, URL and auth client.
   * <p>
   * This is primarily intended for testing scenarios, where a fake auth client is required.
   *
   * @param credentials  the credentials to use for authentication
   * @param serviceUrl  the URL of the service
   * @param authClient  the auth client
   * @return the invoker
   * @deprecated Use the builder for greater clarity and flexibility
   */
  @Deprecated
  public static ServiceInvoker of(Credentials credentials, HttpUrl serviceUrl, AuthClient authClient) {
    return new ServiceInvokerBuilder(credentials)
        .serviceUrl(serviceUrl)
        .authClientFactory(invoker -> authClient)
        .build();
  }

  //-------------------------------------------------------------------------
  // creates an instance
  ServiceInvoker(HttpUrl serviceUrl, OkHttpClient httpClient, ScheduledExecutorService executor) {
    this.serviceUrl = Objects.requireNonNull(serviceUrl, "serviceUrl must not be null");
    this.httpClient = Objects.requireNonNull(httpClient, "httpClient must not be null");
    this.executor = Objects.requireNonNull(executor, "executor must not be null");
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the server URL.
   *
   * @return the executor
   */
  public HttpUrl getServiceUrl() {
    return serviceUrl;
  }

  /**
   * Gets the HTTP client.
   *
   * @return the HTTP client
   */
  public OkHttpClient getHttpClient() {
    return httpClient;
  }

  /**
   * Gets the executor that can be used to poll.
   *
   * @return the executor
   */
  public ScheduledExecutorService getExecutor() {
    return executor;
  }

  //-------------------------------------------------------------------------
  /**
   * Closes access to the remote service.
   * <p>
   * This instance must not be used once this method is called.
   * <p>
   * This closes the executor, but not the HTTP client (as {@link OkHttpClient}
   * advises it should not normally be explicitly closed).
   */
  @Override
  public void close() {
    executor.shutdown();
  }

} public interface Credentials {
  // the design of this interface and the methods that use it are intended to support
  // different ways to authenticate without exposing the implementing classes

  /**
   * Obtains credentials using an API key and secret.
   * <p>
   * This is the recommended way to connect.
   * 
   * @param apiKey  the API key
   * @param secret  the secret
   * @return the credentials
   */
  public static Credentials ofApiKey(String apiKey, String secret) {
    return ApiKeyCredentials.of(apiKey, secret);
  }

  //-------------------------------------------------------------------------
  /**
   * Authenticates using these credentials, returning an access token.
   * 
   * @param client  the client to authenticate with
   * @return the access token result
   * @throws AuthenticationException if unable to authenticate
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract AccessTokenResult authenticate(AuthClient client);

} public class Ccp implements Comparable<Ccp>, Serializable {

  /** ASX (Australian Securities Exchange) SPAN. */
  public static final Ccp ASX_SPAN = new Ccp("ASX_SPAN");
  /** BMD (Bursa Malaysia) SPAN. */
  public static final Ccp BMD_SPAN = new Ccp("BMD_SPAN");
  /** CBOE (Chicago Board Options Exchange) SPAN. */
  public static final Ccp CBOE_SPAN = new Ccp("CBOE_SPAN");
  /** CDCC (Canadian Derivatives Clearing Corporation) SPAN. */
  public static final Ccp CDCC_SPAN = new Ccp("CDCC_SPAN");
  /** CME (Chicago Mercantile Exchange). */
  public static final Ccp CME = new Ccp("CME");
  /** CME (Chicago Mercantile Exchange) SPAN. */
  public static final Ccp CME_SPAN = new Ccp("CME_SPAN");
  /** ECC (European Commodity Clearing) SPAN. */
  public static final Ccp ECC_SPAN = new Ccp("ECC_SPAN");
  /** Eurex. */
  public static final Ccp EUREX = new Ccp("EUREX");
  /** LCH. */
  public static final Ccp LCH = new Ccp("LCH");
  /** LCH CDS. */
  public static final Ccp LCH_CDS = new Ccp("LCH_CDS");
  /** HKEX (Hong Kong Exchange) SPAN. */
  public static final Ccp HKEX_SPAN = new Ccp("HKEX_SPAN");
  /** ICE (Intercontinental Exchange) SPAN. */
  public static final Ccp ICE_SPAN = new Ccp("ICE_SPAN");
  /** JCCH (Japan Commodity Clearing House) SPAN. */
  public static final Ccp JCCH_SPAN = new Ccp("JCCH_SPAN");
  /** JSCC (Japan Securities Clearing Corp). */
  public static final Ccp JSCC = new Ccp("JSCC");
  /** JSCC (Japan Securities Clearing Corp) SPAN. */
  public static final Ccp JSCC_SPAN = new Ccp("JSCC_SPAN");
  /** LME (London Metal Exchange) SPAN. */
  public static final Ccp LME_SPAN = new Ccp("LME_SPAN");
  /** MGE (Minneapolis Grain Exchange) SPAN. */
  public static final Ccp MGE_SPAN = new Ccp("MGE_SPAN");
  /** SGX (Singapore Exchange) SPAN. */
  public static final Ccp SGX_SPAN = new Ccp("SGX_SPAN");
  /** SIMM. */
  public static final Ccp SIMM = new Ccp("SIMM");
  /** TIF (Tokyo Financial Exchange) SPAN. */
  public static final Ccp TIF_SPAN = new Ccp("TIF_SPAN");

  private static final long serialVersionUID = 1L;

  private final String ccpName;

  /**
   * Returns an instance of {@code Ccp} corresponding to the given name.
   *
   * @param ccpName  the name of the CCP
   * @return an instance of {@code Ccp}
   */
  @FromString
  public static Ccp of(String ccpName) {
    JodaBeanUtils.notNull(ccpName, "ccpName");
    return new Ccp(ccpName.toUpperCase(Locale.ENGLISH));
  }

  /**
   * Returns all pre-defined CCPs.
   *
   * @return an array of CCPs
   * @deprecated there are no business cases that require this method, and it will be removed in a future version of the library.
   */
  @Deprecated
  public static Ccp[] values() {
    return new Ccp[]{ASX_SPAN, BMD_SPAN, CBOE_SPAN, CDCC_SPAN, CME, CME_SPAN, ECC_SPAN, EUREX, LCH, LCH_CDS, HKEX_SPAN,
        ICE_SPAN, JCCH_SPAN, JSCC, JSCC_SPAN, LME_SPAN, MGE_SPAN, SGX_SPAN, SIMM, TIF_SPAN};
  }

  /**
   * Returns an instance of {@code Ccp} corresponding to the given name.
   *
   * @param ccpName  the name of the CCP
   * @return an instance of {@code Ccp}
   * @deprecated This method is added for backwards compatibility, and will be removed in a future version of the library.
   *  Please use `of()` instead
   */
  @Deprecated
  public static Ccp valueOf(String ccpName) {
    return of(ccpName);
  }

  private Ccp(String ccpName) {
    this.ccpName = ccpName;
  }

  private Object readResolve() {
    return of(ccpName);
  }

  /**
   * Returns the name of the CCP.
   *
   * @return the name of the CCP
   */
  public String name() {
    return this.ccpName;
  }

  @Override
  public int compareTo(Ccp o) {
    return this.name().compareTo(o.name());
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Ccp ccp = (Ccp) o;
    return Objects.equals(ccpName, ccp.ccpName);
  }

  @Override
  public int hashCode() {
    return Objects.hash(ccpName);
  }

  @Override
  public String toString() {
    return ccpName.toLowerCase(Locale.ENGLISH);
  }
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class CcpInfo implements ImmutableBean {

  /**
   * The list of valuation dates available for the CCP, may be empty.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<LocalDate> valuationDates;
  /**
   * The default currency of the CCP.
   */
  @PropertyDefinition(validate = "notBlank")
  private final String defaultCurrency;
  /**
   * The list of currencies that the report may be reported in, not empty.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<String> reportingCurrencies;
  /**
   * The list of currencies that the calculation can be performed in,
   * empty if it is intended to be inferred from the reporting currency.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<String> calculationCurrencies;
  /**
   * The list of calculation types that are supported.
   */
  @PropertyDefinition(validate = "notNull")
  private final Set<MarginCalcType> calculationTypes;
  /**
   * The list of calculation modes that the calculation can be performed in.
   */
  @PropertyDefinition(validate = "notNull")
  private final Set<MarginCalcMode> calculationModes;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance.
   * 
   * @param valuationDates  the valuation dates
   * @param defaultCurrency  the default currency
   * @param reportingCurrencies  the reporting currencies
   * @param calculationCurrencies  the calculation currencies
   * @return the instance
   * @deprecated Use the 6-arg version of this method
   *   (it is intended that the SDK creates instances of this class, your code should only create instances in tests)
   */
  @Deprecated
  public static CcpInfo of(
      List<LocalDate> valuationDates,
      String defaultCurrency,
      List<String> reportingCurrencies,
      List<String> calculationCurrencies) {

    return new CcpInfo(
        valuationDates,
        defaultCurrency,
        reportingCurrencies,
        calculationCurrencies,
        new HashSet<>(),
        new HashSet<>());
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the latest available valuation date.
   * 
   * @return the latest available valuation date
   * @throws IllegalArgumentException if there are no valid valuation dates
   */
  public LocalDate getLatestValuationDate() {
    return valuationDates.stream()
        .sorted(Comparator.reverseOrder())
        .findFirst()
        .orElseThrow(() -> new IllegalArgumentException("No valuation dates are available"));
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code CcpInfo}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return CcpInfo.Meta.INSTANCE;
  }

  static {
    MetaBean.register(CcpInfo.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param valuationDates  the value of the property, not null
   * @param defaultCurrency  the value of the property, not blank
   * @param reportingCurrencies  the value of the property, not null
   * @param calculationCurrencies  the value of the property, not null
   * @param calculationTypes  the value of the property, not null
   * @param calculationModes  the value of the property, not null
   * @return the instance
   */
  public static CcpInfo of(
      List<LocalDate> valuationDates,
      String defaultCurrency,
      List<String> reportingCurrencies,
      List<String> calculationCurrencies,
      Set<MarginCalcType> calculationTypes,
      Set<MarginCalcMode> calculationModes) {
    return new CcpInfo(
      valuationDates,
      defaultCurrency,
      reportingCurrencies,
      calculationCurrencies,
      calculationTypes,
      calculationModes);
  }

  private CcpInfo(
      List<LocalDate> valuationDates,
      String defaultCurrency,
      List<String> reportingCurrencies,
      List<String> calculationCurrencies,
      Set<MarginCalcType> calculationTypes,
      Set<MarginCalcMode> calculationModes) {
    JodaBeanUtils.notNull(valuationDates, "valuationDates");
    JodaBeanUtils.notBlank(defaultCurrency, "defaultCurrency");
    JodaBeanUtils.notNull(reportingCurrencies, "reportingCurrencies");
    JodaBeanUtils.notNull(calculationCurrencies, "calculationCurrencies");
    JodaBeanUtils.notNull(calculationTypes, "calculationTypes");
    JodaBeanUtils.notNull(calculationModes, "calculationModes");
    this.valuationDates = Collections.unmodifiableList(new ArrayList<>(valuationDates));
    this.defaultCurrency = defaultCurrency;
    this.reportingCurrencies = Collections.unmodifiableList(new ArrayList<>(reportingCurrencies));
    this.calculationCurrencies = Collections.unmodifiableList(new ArrayList<>(calculationCurrencies));
    this.calculationTypes = Collections.unmodifiableSet(new HashSet<>(calculationTypes));
    this.calculationModes = Collections.unmodifiableSet(new HashSet<>(calculationModes));
  }

  @Override
  public MetaBean metaBean() {
    return CcpInfo.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of valuation dates available for the CCP, may be empty.
   * @return the value of the property, not null
   */
  public List<LocalDate> getValuationDates() {
    return valuationDates;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the default currency of the CCP.
   * @return the value of the property, not blank
   */
  public String getDefaultCurrency() {
    return defaultCurrency;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of currencies that the report may be reported in, not empty.
   * @return the value of the property, not null
   */
  public List<String> getReportingCurrencies() {
    return reportingCurrencies;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of currencies that the calculation can be performed in,
   * empty if it is intended to be inferred from the reporting currency.
   * @return the value of the property, not null
   */
  public List<String> getCalculationCurrencies() {
    return calculationCurrencies;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of calculation types that are supported.
   * @return the value of the property, not null
   */
  public Set<MarginCalcType> getCalculationTypes() {
    return calculationTypes;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of calculation modes that the calculation can be performed in.
   * @return the value of the property, not null
   */
  public Set<MarginCalcMode> getCalculationModes() {
    return calculationModes;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      CcpInfo other = (CcpInfo) obj;
      return JodaBeanUtils.equal(valuationDates, other.valuationDates) &&
          JodaBeanUtils.equal(defaultCurrency, other.defaultCurrency) &&
          JodaBeanUtils.equal(reportingCurrencies, other.reportingCurrencies) &&
          JodaBeanUtils.equal(calculationCurrencies, other.calculationCurrencies) &&
          JodaBeanUtils.equal(calculationTypes, other.calculationTypes) &&
          JodaBeanUtils.equal(calculationModes, other.calculationModes);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(valuationDates);
    hash = hash * 31 + JodaBeanUtils.hashCode(defaultCurrency);
    hash = hash * 31 + JodaBeanUtils.hashCode(reportingCurrencies);
    hash = hash * 31 + JodaBeanUtils.hashCode(calculationCurrencies);
    hash = hash * 31 + JodaBeanUtils.hashCode(calculationTypes);
    hash = hash * 31 + JodaBeanUtils.hashCode(calculationModes);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(224);
    buf.append("CcpInfo{");
    buf.append("valuationDates").append('=').append(JodaBeanUtils.toString(valuationDates)).append(',').append(' ');
    buf.append("defaultCurrency").append('=').append(JodaBeanUtils.toString(defaultCurrency)).append(',').append(' ');
    buf.append("reportingCurrencies").append('=').append(JodaBeanUtils.toString(reportingCurrencies)).append(',').append(' ');
    buf.append("calculationCurrencies").append('=').append(JodaBeanUtils.toString(calculationCurrencies)).append(',').append(' ');
    buf.append("calculationTypes").append('=').append(JodaBeanUtils.toString(calculationTypes)).append(',').append(' ');
    buf.append("calculationModes").append('=').append(JodaBeanUtils.toString(calculationModes));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code CcpInfo}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code valuationDates} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<LocalDate>> valuationDates = DirectMetaProperty.ofImmutable(
        this, "valuationDates", CcpInfo.class, (Class) List.class);
    /**
     * The meta-property for the {@code defaultCurrency} property.
     */
    private final MetaProperty<String> defaultCurrency = DirectMetaProperty.ofImmutable(
        this, "defaultCurrency", CcpInfo.class, String.class);
    /**
     * The meta-property for the {@code reportingCurrencies} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<String>> reportingCurrencies = DirectMetaProperty.ofImmutable(
        this, "reportingCurrencies", CcpInfo.class, (Class) List.class);
    /**
     * The meta-property for the {@code calculationCurrencies} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<String>> calculationCurrencies = DirectMetaProperty.ofImmutable(
        this, "calculationCurrencies", CcpInfo.class, (Class) List.class);
    /**
     * The meta-property for the {@code calculationTypes} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<Set<MarginCalcType>> calculationTypes = DirectMetaProperty.ofImmutable(
        this, "calculationTypes", CcpInfo.class, (Class) Set.class);
    /**
     * The meta-property for the {@code calculationModes} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<Set<MarginCalcMode>> calculationModes = DirectMetaProperty.ofImmutable(
        this, "calculationModes", CcpInfo.class, (Class) Set.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "valuationDates",
        "defaultCurrency",
        "reportingCurrencies",
        "calculationCurrencies",
        "calculationTypes",
        "calculationModes");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case -788641532:  // valuationDates
          return valuationDates;
        case -1721476750:  // defaultCurrency
          return defaultCurrency;
        case -668253891:  // reportingCurrencies
          return reportingCurrencies;
        case 830379032:  // calculationCurrencies
          return calculationCurrencies;
        case 755457840:  // calculationTypes
          return calculationTypes;
        case 748683751:  // calculationModes
          return calculationModes;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends CcpInfo> builder() {
      return new CcpInfo.Builder();
    }

    @Override
    public Class<? extends CcpInfo> beanType() {
      return CcpInfo.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -788641532:  // valuationDates
          return ((CcpInfo) bean).getValuationDates();
        case -1721476750:  // defaultCurrency
          return ((CcpInfo) bean).getDefaultCurrency();
        case -668253891:  // reportingCurrencies
          return ((CcpInfo) bean).getReportingCurrencies();
        case 830379032:  // calculationCurrencies
          return ((CcpInfo) bean).getCalculationCurrencies();
        case 755457840:  // calculationTypes
          return ((CcpInfo) bean).getCalculationTypes();
        case 748683751:  // calculationModes
          return ((CcpInfo) bean).getCalculationModes();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code CcpInfo}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<CcpInfo> {

    private List<LocalDate> valuationDates = Collections.emptyList();
    private String defaultCurrency;
    private List<String> reportingCurrencies = Collections.emptyList();
    private List<String> calculationCurrencies = Collections.emptyList();
    private Set<MarginCalcType> calculationTypes = Collections.emptySet();
    private Set<MarginCalcMode> calculationModes = Collections.emptySet();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case -788641532:  // valuationDates
          return valuationDates;
        case -1721476750:  // defaultCurrency
          return defaultCurrency;
        case -668253891:  // reportingCurrencies
          return reportingCurrencies;
        case 830379032:  // calculationCurrencies
          return calculationCurrencies;
        case 755457840:  // calculationTypes
          return calculationTypes;
        case 748683751:  // calculationModes
          return calculationModes;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case -788641532:  // valuationDates
          this.valuationDates = (List<LocalDate>) newValue;
          break;
        case -1721476750:  // defaultCurrency
          this.defaultCurrency = (String) newValue;
          break;
        case -668253891:  // reportingCurrencies
          this.reportingCurrencies = (List<String>) newValue;
          break;
        case 830379032:  // calculationCurrencies
          this.calculationCurrencies = (List<String>) newValue;
          break;
        case 755457840:  // calculationTypes
          this.calculationTypes = (Set<MarginCalcType>) newValue;
          break;
        case 748683751:  // calculationModes
          this.calculationModes = (Set<MarginCalcMode>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public CcpInfo build() {
      return new CcpInfo(
          valuationDates,
          defaultCurrency,
          reportingCurrencies,
          calculationCurrencies,
          calculationTypes,
          calculationModes);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(224);
      buf.append("CcpInfo.Builder{");
      buf.append("valuationDates").append('=').append(JodaBeanUtils.toString(valuationDates)).append(',').append(' ');
      buf.append("defaultCurrency").append('=').append(JodaBeanUtils.toString(defaultCurrency)).append(',').append(' ');
      buf.append("reportingCurrencies").append('=').append(JodaBeanUtils.toString(reportingCurrencies)).append(',').append(' ');
      buf.append("calculationCurrencies").append('=').append(JodaBeanUtils.toString(calculationCurrencies)).append(',').append(' ');
      buf.append("calculationTypes").append('=').append(JodaBeanUtils.toString(calculationTypes)).append(',').append(' ');
      buf.append("calculationModes").append('=').append(JodaBeanUtils.toString(calculationModes));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class CcpsResult implements ImmutableBean {

  /**
   * The list of available CCPs, may be empty.
   * <p>
   * This is returned in string form in case the server returns a CCP that is not known by the client.
   */
  @PropertyDefinition(validate = "notNull", alias = "ccps")
  private final List<String> ccpNames;

  //-------------------------------------------------------------------------
  /**
   * Gets the list of available CCPs, may be empty.
   * 
   * @return the list of available CCPs
   */
  public List<Ccp> getCcps() {
    List<Ccp> ccps = new ArrayList<>();
    for (String name : ccpNames) {
      try {
        ccps.add(Ccp.of(name));
      } catch (RuntimeException ex) {
        // ignore, server may be newer than client
      }
    }
    return ccps;
  }

  /**
   * Checks if the CCP is available.
   * 
   * @param ccpName  the CCP to check
   * @return true if available to uses
   */
  public boolean isCcpAvailable(String ccpName) {
    return ccpNames.stream().anyMatch(ccpName::equalsIgnoreCase);
  }

  /**
   * Checks if the CCP is available.
   * 
   * @param ccp  the CCP to check
   * @return true if available to uses
   */
  public boolean isCcpAvailable(Ccp ccp) {
    return ccpNames.stream().anyMatch(x -> ccp.name().equalsIgnoreCase(x));
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code CcpsResult}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return CcpsResult.Meta.INSTANCE;
  }

  static {
    MetaBean.register(CcpsResult.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param ccpNames  the value of the property, not null
   * @return the instance
   */
  public static CcpsResult of(
      List<String> ccpNames) {
    return new CcpsResult(
      ccpNames);
  }

  private CcpsResult(
      List<String> ccpNames) {
    JodaBeanUtils.notNull(ccpNames, "ccpNames");
    this.ccpNames = Collections.unmodifiableList(new ArrayList<>(ccpNames));
  }

  @Override
  public MetaBean metaBean() {
    return CcpsResult.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of available CCPs, may be empty.
   * <p>
   * This is returned in string form in case the server returns a CCP that is not known by the client.
   * @return the value of the property, not null
   */
  public List<String> getCcpNames() {
    return ccpNames;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      CcpsResult other = (CcpsResult) obj;
      return JodaBeanUtils.equal(ccpNames, other.ccpNames);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(ccpNames);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(64);
    buf.append("CcpsResult{");
    buf.append("ccpNames").append('=').append(JodaBeanUtils.toString(ccpNames));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code CcpsResult}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code ccpNames} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<String>> ccpNames = DirectMetaProperty.ofImmutable(
        this, "ccpNames", CcpsResult.class, (Class) List.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "ccpNames");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 1689579800:  // ccpNames
        case 3048035:  // ccps (alias)
          return ccpNames;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends CcpsResult> builder() {
      return new CcpsResult.Builder();
    }

    @Override
    public Class<? extends CcpsResult> beanType() {
      return CcpsResult.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 1689579800:  // ccpNames
        case 3048035:  // ccps (alias)
          return ((CcpsResult) bean).getCcpNames();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code CcpsResult}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<CcpsResult> {

    private List<String> ccpNames = Collections.emptyList();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 1689579800:  // ccpNames
        case 3048035:  // ccps (alias)
          return ccpNames;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 1689579800:  // ccpNames
        case 3048035:  // ccps (alias)
          this.ccpNames = (List<String>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public CcpsResult build() {
      return new CcpsResult(
          ccpNames);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(64);
      buf.append("CcpsResult.Builder{");
      buf.append("ccpNames").append('=').append(JodaBeanUtils.toString(ccpNames));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class LchMarginDetail extends MarginDetail implements ImmutableBean {

  /**
   * The total margin, expressed in the reporting currency.
   * This is the sum of the base margin and the add-ons.
   */
  @PropertyDefinition(validate = "notNull")
  private final double totalMargin;
  /**
   * The identifiers of the scenarios used to calculate margin for the diversified portfolio.
   * Use {@link #findScenario(String)} to retrieve the scenario details.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<String> baseScenarioIds;
  /**
   * The indices contained in the portfolio.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<LchMarginIndex> indices;
  /**
   * The scenarios used to calculate margin.
   * This consists only of those scenarios that were actively used in the portfolio
   * level diversified or the index level undiversified calculation.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<LchMarginScenario> scenarios;

  //-------------------------------------------------------------------------
  @Override
  @DerivedProperty
  public Ccp getCcp() {
    return Ccp.LCH;
  }

  /**
   * Finds the first index matching by name.
   * 
   * @param indexName the index name
   * @return the optional index
   */
  public Optional<LchMarginIndex> findIndex(String indexName) {
    return indices.stream()
        .filter(val -> val.getIndexName().equalsIgnoreCase(indexName))
        .findFirst();
  }

  /**
   * Finds the first scenario matching by identifier.
   * 
   * @param scenarioId the scenario identifier
   * @return the optional scenario
   */
  public Optional<LchMarginScenario> findScenario(String scenarioId) {
    return scenarios.stream()
        .filter(val -> val.getId().equalsIgnoreCase(scenarioId))
        .findFirst();
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code LchMarginDetail}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return LchMarginDetail.Meta.INSTANCE;
  }

  static {
    MetaBean.register(LchMarginDetail.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param totalMargin  the value of the property, not null
   * @param baseScenarioIds  the value of the property, not null
   * @param indices  the value of the property, not null
   * @param scenarios  the value of the property, not null
   * @return the instance
   */
  public static LchMarginDetail of(
      double totalMargin,
      List<String> baseScenarioIds,
      List<LchMarginIndex> indices,
      List<LchMarginScenario> scenarios) {
    return new LchMarginDetail(
      totalMargin,
      baseScenarioIds,
      indices,
      scenarios);
  }

  private LchMarginDetail(
      double totalMargin,
      List<String> baseScenarioIds,
      List<LchMarginIndex> indices,
      List<LchMarginScenario> scenarios) {
    JodaBeanUtils.notNull(totalMargin, "totalMargin");
    JodaBeanUtils.notNull(baseScenarioIds, "baseScenarioIds");
    JodaBeanUtils.notNull(indices, "indices");
    JodaBeanUtils.notNull(scenarios, "scenarios");
    this.totalMargin = totalMargin;
    this.baseScenarioIds = Collections.unmodifiableList(new ArrayList<>(baseScenarioIds));
    this.indices = Collections.unmodifiableList(new ArrayList<>(indices));
    this.scenarios = Collections.unmodifiableList(new ArrayList<>(scenarios));
  }

  @Override
  public MetaBean metaBean() {
    return LchMarginDetail.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the total margin, expressed in the reporting currency.
   * This is the sum of the base margin and the add-ons.
   * @return the value of the property, not null
   */
  public double getTotalMargin() {
    return totalMargin;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the identifiers of the scenarios used to calculate margin for the diversified portfolio.
   * Use {@link #findScenario(String)} to retrieve the scenario details.
   * @return the value of the property, not null
   */
  public List<String> getBaseScenarioIds() {
    return baseScenarioIds;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the indices contained in the portfolio.
   * @return the value of the property, not null
   */
  public List<LchMarginIndex> getIndices() {
    return indices;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the scenarios used to calculate margin.
   * This consists only of those scenarios that were actively used in the portfolio
   * level diversified or the index level undiversified calculation.
   * @return the value of the property, not null
   */
  public List<LchMarginScenario> getScenarios() {
    return scenarios;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      LchMarginDetail other = (LchMarginDetail) obj;
      return JodaBeanUtils.equal(totalMargin, other.totalMargin) &&
          JodaBeanUtils.equal(baseScenarioIds, other.baseScenarioIds) &&
          JodaBeanUtils.equal(indices, other.indices) &&
          JodaBeanUtils.equal(scenarios, other.scenarios);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(totalMargin);
    hash = hash * 31 + JodaBeanUtils.hashCode(baseScenarioIds);
    hash = hash * 31 + JodaBeanUtils.hashCode(indices);
    hash = hash * 31 + JodaBeanUtils.hashCode(scenarios);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(192);
    buf.append("LchMarginDetail{");
    buf.append("totalMargin").append('=').append(JodaBeanUtils.toString(totalMargin)).append(',').append(' ');
    buf.append("baseScenarioIds").append('=').append(JodaBeanUtils.toString(baseScenarioIds)).append(',').append(' ');
    buf.append("indices").append('=').append(JodaBeanUtils.toString(indices)).append(',').append(' ');
    buf.append("scenarios").append('=').append(JodaBeanUtils.toString(scenarios)).append(',').append(' ');
    buf.append("ccp").append('=').append(JodaBeanUtils.toString(getCcp()));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code LchMarginDetail}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code totalMargin} property.
     */
    private final MetaProperty<Double> totalMargin = DirectMetaProperty.ofImmutable(
        this, "totalMargin", LchMarginDetail.class, Double.TYPE);
    /**
     * The meta-property for the {@code baseScenarioIds} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<String>> baseScenarioIds = DirectMetaProperty.ofImmutable(
        this, "baseScenarioIds", LchMarginDetail.class, (Class) List.class);
    /**
     * The meta-property for the {@code indices} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<LchMarginIndex>> indices = DirectMetaProperty.ofImmutable(
        this, "indices", LchMarginDetail.class, (Class) List.class);
    /**
     * The meta-property for the {@code scenarios} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<LchMarginScenario>> scenarios = DirectMetaProperty.ofImmutable(
        this, "scenarios", LchMarginDetail.class, (Class) List.class);
    /**
     * The meta-property for the {@code ccp} property.
     */
    private final MetaProperty<Ccp> ccp = DirectMetaProperty.ofDerived(
        this, "ccp", LchMarginDetail.class, Ccp.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "totalMargin",
        "baseScenarioIds",
        "indices",
        "scenarios",
        "ccp");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case -924857838:  // totalMargin
          return totalMargin;
        case -586668681:  // baseScenarioIds
          return baseScenarioIds;
        case 1943391143:  // indices
          return indices;
        case 1726545635:  // scenarios
          return scenarios;
        case 98320:  // ccp
          return ccp;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends LchMarginDetail> builder() {
      return new LchMarginDetail.Builder();
    }

    @Override
    public Class<? extends LchMarginDetail> beanType() {
      return LchMarginDetail.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -924857838:  // totalMargin
          return ((LchMarginDetail) bean).getTotalMargin();
        case -586668681:  // baseScenarioIds
          return ((LchMarginDetail) bean).getBaseScenarioIds();
        case 1943391143:  // indices
          return ((LchMarginDetail) bean).getIndices();
        case 1726545635:  // scenarios
          return ((LchMarginDetail) bean).getScenarios();
        case 98320:  // ccp
          return ((LchMarginDetail) bean).getCcp();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code LchMarginDetail}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<LchMarginDetail> {

    private double totalMargin;
    private List<String> baseScenarioIds = Collections.emptyList();
    private List<LchMarginIndex> indices = Collections.emptyList();
    private List<LchMarginScenario> scenarios = Collections.emptyList();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case -924857838:  // totalMargin
          return totalMargin;
        case -586668681:  // baseScenarioIds
          return baseScenarioIds;
        case 1943391143:  // indices
          return indices;
        case 1726545635:  // scenarios
          return scenarios;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case -924857838:  // totalMargin
          this.totalMargin = (Double) newValue;
          break;
        case -586668681:  // baseScenarioIds
          this.baseScenarioIds = (List<String>) newValue;
          break;
        case 1943391143:  // indices
          this.indices = (List<LchMarginIndex>) newValue;
          break;
        case 1726545635:  // scenarios
          this.scenarios = (List<LchMarginScenario>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public LchMarginDetail build() {
      return new LchMarginDetail(
          totalMargin,
          baseScenarioIds,
          indices,
          scenarios);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(192);
      buf.append("LchMarginDetail.Builder{");
      buf.append("totalMargin").append('=').append(JodaBeanUtils.toString(totalMargin)).append(',').append(' ');
      buf.append("baseScenarioIds").append('=').append(JodaBeanUtils.toString(baseScenarioIds)).append(',').append(' ');
      buf.append("indices").append('=').append(JodaBeanUtils.toString(indices)).append(',').append(' ');
      buf.append("scenarios").append('=').append(JodaBeanUtils.toString(scenarios)).append(',').append(' ');
      buf.append("ccp").append('=').append(JodaBeanUtils.toString(null));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class LchMarginIndex implements ImmutableBean {

  /**
   * The index name.
   */
  @PropertyDefinition(validate = "notNull")
  private final String indexName;
  /**
   * The diversified base margin for the index, expressed in the reporting currency.
   */
  @PropertyDefinition
  private final double diversifiedBaseMargin;
  /**
   * The undiversified base margin for the index, expressed in the reporting currency.
   */
  @PropertyDefinition
  private final double undiversifiedBaseMargin;
  /**
   * The identifiers of the scenarios used to calculate margin for the index.
   * The scenarios can be accessed from {@link LchMarginDetail#findScenario(String)}.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<String> indexScenarioIds;

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code LchMarginIndex}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return LchMarginIndex.Meta.INSTANCE;
  }

  static {
    MetaBean.register(LchMarginIndex.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param indexName  the value of the property, not null
   * @param diversifiedBaseMargin  the value of the property
   * @param undiversifiedBaseMargin  the value of the property
   * @param indexScenarioIds  the value of the property, not null
   * @return the instance
   */
  public static LchMarginIndex of(
      String indexName,
      double diversifiedBaseMargin,
      double undiversifiedBaseMargin,
      List<String> indexScenarioIds) {
    return new LchMarginIndex(
      indexName,
      diversifiedBaseMargin,
      undiversifiedBaseMargin,
      indexScenarioIds);
  }

  private LchMarginIndex(
      String indexName,
      double diversifiedBaseMargin,
      double undiversifiedBaseMargin,
      List<String> indexScenarioIds) {
    JodaBeanUtils.notNull(indexName, "indexName");
    JodaBeanUtils.notNull(indexScenarioIds, "indexScenarioIds");
    this.indexName = indexName;
    this.diversifiedBaseMargin = diversifiedBaseMargin;
    this.undiversifiedBaseMargin = undiversifiedBaseMargin;
    this.indexScenarioIds = Collections.unmodifiableList(new ArrayList<>(indexScenarioIds));
  }

  @Override
  public MetaBean metaBean() {
    return LchMarginIndex.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the index name.
   * @return the value of the property, not null
   */
  public String getIndexName() {
    return indexName;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the diversified base margin for the index, expressed in the reporting currency.
   * @return the value of the property
   */
  public double getDiversifiedBaseMargin() {
    return diversifiedBaseMargin;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the undiversified base margin for the index, expressed in the reporting currency.
   * @return the value of the property
   */
  public double getUndiversifiedBaseMargin() {
    return undiversifiedBaseMargin;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the identifiers of the scenarios used to calculate margin for the index.
   * The scenarios can be accessed from {@link LchMarginDetail#findScenario(String)}.
   * @return the value of the property, not null
   */
  public List<String> getIndexScenarioIds() {
    return indexScenarioIds;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      LchMarginIndex other = (LchMarginIndex) obj;
      return JodaBeanUtils.equal(indexName, other.indexName) &&
          JodaBeanUtils.equal(diversifiedBaseMargin, other.diversifiedBaseMargin) &&
          JodaBeanUtils.equal(undiversifiedBaseMargin, other.undiversifiedBaseMargin) &&
          JodaBeanUtils.equal(indexScenarioIds, other.indexScenarioIds);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(indexName);
    hash = hash * 31 + JodaBeanUtils.hashCode(diversifiedBaseMargin);
    hash = hash * 31 + JodaBeanUtils.hashCode(undiversifiedBaseMargin);
    hash = hash * 31 + JodaBeanUtils.hashCode(indexScenarioIds);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(160);
    buf.append("LchMarginIndex{");
    buf.append("indexName").append('=').append(JodaBeanUtils.toString(indexName)).append(',').append(' ');
    buf.append("diversifiedBaseMargin").append('=').append(JodaBeanUtils.toString(diversifiedBaseMargin)).append(',').append(' ');
    buf.append("undiversifiedBaseMargin").append('=').append(JodaBeanUtils.toString(undiversifiedBaseMargin)).append(',').append(' ');
    buf.append("indexScenarioIds").append('=').append(JodaBeanUtils.toString(indexScenarioIds));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code LchMarginIndex}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code indexName} property.
     */
    private final MetaProperty<String> indexName = DirectMetaProperty.ofImmutable(
        this, "indexName", LchMarginIndex.class, String.class);
    /**
     * The meta-property for the {@code diversifiedBaseMargin} property.
     */
    private final MetaProperty<Double> diversifiedBaseMargin = DirectMetaProperty.ofImmutable(
        this, "diversifiedBaseMargin", LchMarginIndex.class, Double.TYPE);
    /**
     * The meta-property for the {@code undiversifiedBaseMargin} property.
     */
    private final MetaProperty<Double> undiversifiedBaseMargin = DirectMetaProperty.ofImmutable(
        this, "undiversifiedBaseMargin", LchMarginIndex.class, Double.TYPE);
    /**
     * The meta-property for the {@code indexScenarioIds} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<String>> indexScenarioIds = DirectMetaProperty.ofImmutable(
        this, "indexScenarioIds", LchMarginIndex.class, (Class) List.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "indexName",
        "diversifiedBaseMargin",
        "undiversifiedBaseMargin",
        "indexScenarioIds");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case -807707011:  // indexName
          return indexName;
        case -1581942027:  // diversifiedBaseMargin
          return diversifiedBaseMargin;
        case 1473689084:  // undiversifiedBaseMargin
          return undiversifiedBaseMargin;
        case -993826602:  // indexScenarioIds
          return indexScenarioIds;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends LchMarginIndex> builder() {
      return new LchMarginIndex.Builder();
    }

    @Override
    public Class<? extends LchMarginIndex> beanType() {
      return LchMarginIndex.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -807707011:  // indexName
          return ((LchMarginIndex) bean).getIndexName();
        case -1581942027:  // diversifiedBaseMargin
          return ((LchMarginIndex) bean).getDiversifiedBaseMargin();
        case 1473689084:  // undiversifiedBaseMargin
          return ((LchMarginIndex) bean).getUndiversifiedBaseMargin();
        case -993826602:  // indexScenarioIds
          return ((LchMarginIndex) bean).getIndexScenarioIds();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code LchMarginIndex}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<LchMarginIndex> {

    private String indexName;
    private double diversifiedBaseMargin;
    private double undiversifiedBaseMargin;
    private List<String> indexScenarioIds = Collections.emptyList();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case -807707011:  // indexName
          return indexName;
        case -1581942027:  // diversifiedBaseMargin
          return diversifiedBaseMargin;
        case 1473689084:  // undiversifiedBaseMargin
          return undiversifiedBaseMargin;
        case -993826602:  // indexScenarioIds
          return indexScenarioIds;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case -807707011:  // indexName
          this.indexName = (String) newValue;
          break;
        case -1581942027:  // diversifiedBaseMargin
          this.diversifiedBaseMargin = (Double) newValue;
          break;
        case 1473689084:  // undiversifiedBaseMargin
          this.undiversifiedBaseMargin = (Double) newValue;
          break;
        case -993826602:  // indexScenarioIds
          this.indexScenarioIds = (List<String>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public LchMarginIndex build() {
      return new LchMarginIndex(
          indexName,
          diversifiedBaseMargin,
          undiversifiedBaseMargin,
          indexScenarioIds);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(160);
      buf.append("LchMarginIndex.Builder{");
      buf.append("indexName").append('=').append(JodaBeanUtils.toString(indexName)).append(',').append(' ');
      buf.append("diversifiedBaseMargin").append('=').append(JodaBeanUtils.toString(diversifiedBaseMargin)).append(',').append(' ');
      buf.append("undiversifiedBaseMargin").append('=').append(JodaBeanUtils.toString(undiversifiedBaseMargin)).append(',').append(' ');
      buf.append("indexScenarioIds").append('=').append(JodaBeanUtils.toString(indexScenarioIds));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class LchMarginScenario implements ImmutableBean {

  /**
   * The scenario identifier.
   */
  @PropertyDefinition(validate = "notNull")
  private final String id;
  /**
   * The date of the scenario.
   */
  @PropertyDefinition
  private final LocalDate date;
  /**
   * The scaled profit-and-loss at the portfolio level, expressed in the reporting currency.
   */
  @PropertyDefinition(validate = "notNull")
  private final double scaledPortfolioPnl;
  /**
   * The unscaled profit-and-loss at the portfolio level, expressed in the reporting currency.
   */
  @PropertyDefinition(validate = "notNull")
  private final double unscaledPortfolioPnl;

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code LchMarginScenario}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return LchMarginScenario.Meta.INSTANCE;
  }

  static {
    MetaBean.register(LchMarginScenario.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param id  the value of the property, not null
   * @param date  the value of the property
   * @param scaledPortfolioPnl  the value of the property, not null
   * @param unscaledPortfolioPnl  the value of the property, not null
   * @return the instance
   */
  public static LchMarginScenario of(
      String id,
      LocalDate date,
      double scaledPortfolioPnl,
      double unscaledPortfolioPnl) {
    return new LchMarginScenario(
      id,
      date,
      scaledPortfolioPnl,
      unscaledPortfolioPnl);
  }

  private LchMarginScenario(
      String id,
      LocalDate date,
      double scaledPortfolioPnl,
      double unscaledPortfolioPnl) {
    JodaBeanUtils.notNull(id, "id");
    JodaBeanUtils.notNull(scaledPortfolioPnl, "scaledPortfolioPnl");
    JodaBeanUtils.notNull(unscaledPortfolioPnl, "unscaledPortfolioPnl");
    this.id = id;
    this.date = date;
    this.scaledPortfolioPnl = scaledPortfolioPnl;
    this.unscaledPortfolioPnl = unscaledPortfolioPnl;
  }

  @Override
  public MetaBean metaBean() {
    return LchMarginScenario.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the scenario identifier.
   * @return the value of the property, not null
   */
  public String getId() {
    return id;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the date of the scenario.
   * @return the value of the property
   */
  public LocalDate getDate() {
    return date;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the scaled profit-and-loss at the portfolio level, expressed in the reporting currency.
   * @return the value of the property, not null
   */
  public double getScaledPortfolioPnl() {
    return scaledPortfolioPnl;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the unscaled profit-and-loss at the portfolio level, expressed in the reporting currency.
   * @return the value of the property, not null
   */
  public double getUnscaledPortfolioPnl() {
    return unscaledPortfolioPnl;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      LchMarginScenario other = (LchMarginScenario) obj;
      return JodaBeanUtils.equal(id, other.id) &&
          JodaBeanUtils.equal(date, other.date) &&
          JodaBeanUtils.equal(scaledPortfolioPnl, other.scaledPortfolioPnl) &&
          JodaBeanUtils.equal(unscaledPortfolioPnl, other.unscaledPortfolioPnl);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(id);
    hash = hash * 31 + JodaBeanUtils.hashCode(date);
    hash = hash * 31 + JodaBeanUtils.hashCode(scaledPortfolioPnl);
    hash = hash * 31 + JodaBeanUtils.hashCode(unscaledPortfolioPnl);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(160);
    buf.append("LchMarginScenario{");
    buf.append("id").append('=').append(JodaBeanUtils.toString(id)).append(',').append(' ');
    buf.append("date").append('=').append(JodaBeanUtils.toString(date)).append(',').append(' ');
    buf.append("scaledPortfolioPnl").append('=').append(JodaBeanUtils.toString(scaledPortfolioPnl)).append(',').append(' ');
    buf.append("unscaledPortfolioPnl").append('=').append(JodaBeanUtils.toString(unscaledPortfolioPnl));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code LchMarginScenario}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code id} property.
     */
    private final MetaProperty<String> id = DirectMetaProperty.ofImmutable(
        this, "id", LchMarginScenario.class, String.class);
    /**
     * The meta-property for the {@code date} property.
     */
    private final MetaProperty<LocalDate> date = DirectMetaProperty.ofImmutable(
        this, "date", LchMarginScenario.class, LocalDate.class);
    /**
     * The meta-property for the {@code scaledPortfolioPnl} property.
     */
    private final MetaProperty<Double> scaledPortfolioPnl = DirectMetaProperty.ofImmutable(
        this, "scaledPortfolioPnl", LchMarginScenario.class, Double.TYPE);
    /**
     * The meta-property for the {@code unscaledPortfolioPnl} property.
     */
    private final MetaProperty<Double> unscaledPortfolioPnl = DirectMetaProperty.ofImmutable(
        this, "unscaledPortfolioPnl", LchMarginScenario.class, Double.TYPE);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "id",
        "date",
        "scaledPortfolioPnl",
        "unscaledPortfolioPnl");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 3355:  // id
          return id;
        case 3076014:  // date
          return date;
        case 670338368:  // scaledPortfolioPnl
          return scaledPortfolioPnl;
        case 1679919001:  // unscaledPortfolioPnl
          return unscaledPortfolioPnl;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends LchMarginScenario> builder() {
      return new LchMarginScenario.Builder();
    }

    @Override
    public Class<? extends LchMarginScenario> beanType() {
      return LchMarginScenario.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 3355:  // id
          return ((LchMarginScenario) bean).getId();
        case 3076014:  // date
          return ((LchMarginScenario) bean).getDate();
        case 670338368:  // scaledPortfolioPnl
          return ((LchMarginScenario) bean).getScaledPortfolioPnl();
        case 1679919001:  // unscaledPortfolioPnl
          return ((LchMarginScenario) bean).getUnscaledPortfolioPnl();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code LchMarginScenario}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<LchMarginScenario> {

    private String id;
    private LocalDate date;
    private double scaledPortfolioPnl;
    private double unscaledPortfolioPnl;

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 3355:  // id
          return id;
        case 3076014:  // date
          return date;
        case 670338368:  // scaledPortfolioPnl
          return scaledPortfolioPnl;
        case 1679919001:  // unscaledPortfolioPnl
          return unscaledPortfolioPnl;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 3355:  // id
          this.id = (String) newValue;
          break;
        case 3076014:  // date
          this.date = (LocalDate) newValue;
          break;
        case 670338368:  // scaledPortfolioPnl
          this.scaledPortfolioPnl = (Double) newValue;
          break;
        case 1679919001:  // unscaledPortfolioPnl
          this.unscaledPortfolioPnl = (Double) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public LchMarginScenario build() {
      return new LchMarginScenario(
          id,
          date,
          scaledPortfolioPnl,
          unscaledPortfolioPnl);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(160);
      buf.append("LchMarginScenario.Builder{");
      buf.append("id").append('=').append(JodaBeanUtils.toString(id)).append(',').append(' ');
      buf.append("date").append('=').append(JodaBeanUtils.toString(date)).append(',').append(' ');
      buf.append("scaledPortfolioPnl").append('=').append(JodaBeanUtils.toString(scaledPortfolioPnl)).append(',').append(' ');
      buf.append("unscaledPortfolioPnl").append('=').append(JodaBeanUtils.toString(unscaledPortfolioPnl));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} public enum MarginCalcMode {

  /**
   * Runs the margin calculation in Spot mode.
   */
  SPOT,

  /**
   * Runs the margin calculation in Forward Approximation mode.
   */
  FORWARD

} @BeanDefinition(metaScope = "private")
@SuppressWarnings("deprecation")
public final class MarginCalcRequest implements ImmutableBean {

  /**
   * The type of calculation to perform.
   * <p>
   * This has been replaced by {@link #getCalculationTypes()}, which provides
   * more control and more features.
   * If {@code PARSE_INPUTS} or {@code FULL} is set, the calculation types will include {@code PORTFOLIO_SUMMARY}.
   * If {@code STANDARD} or {@code FULL} is set, the calculation types will include {@code MARGIN}.
   * 
   * @deprecated Use {@link #getCalculationTypes()} instead
   */
  @Deprecated
  @PropertyDefinition(get = "field", toStringStyle = "omit")
  private final MarginCalcRequestType type;
  /**
   * The types of information to include in the output.
   * <p>
   * If an empty set is passed in, the output type {@link MarginCalcType#MARGIN MARGIN} will be used.
   */
  @PropertyDefinition(validate = "notNull")
  private final Set<MarginCalcType> calculationTypes;
  /**
   * The mode of the calculation, defaulted to {@code SPOT}.
   */
  @PropertyDefinition(validate = "notNull")
  private final MarginCalcMode mode;
  /**
   * The valuation date for which the portfolio will be processed.
   */
  @PropertyDefinition(validate = "notNull")
  private final LocalDate valuationDate;
  /**
   * Whether to apply the client multiplier, default false.
   */
  @PropertyDefinition
  private final boolean applyClientMultiplier;
  /**
   * The currency that the result is reported in, as an ISO 4217 three letter currency code.
   */
  @PropertyDefinition(validate = "notNull")
  private final String reportingCurrency;
  /**
   * The optional currency that the calculation is performed in, as an ISO 4217 three letter currency code.
   * If omitted, the calculation currency will be inferred from the reportingCurrency.
   */
  @PropertyDefinition(get = "optional")
  private final String calculationCurrency;
  /**
   * The portfolio data, where each entry typically represents a CSV, TSV or XML file.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<PortfolioDataFile> portfolioData;
  /**
   * The regular expression used to select the party in any FpML input.
   * The regular expression is matched against the content of the {@code partyId} elements.
   * If this is not specified, FpML cannot be parsed.
   */
  @PropertyDefinition(get = "optional")
  private final String fpmlPartySelectionRegex;
  /**
   * To have self-referencing margin calculated correctly, we need to pass in (if specified) the clearing member code.
   */
  @PropertyDefinition(get = "optional")
  private final String portfolioOwnerCode;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance that requests a standard margin calculation.
   * <p>
   * The list of portfolio data should be either {@link PortfolioDataFile} instances
   * or Strata {@code CalculationTarget} instances, such as trades or positions.
   * Defaults the {@link MarginCalcMode} to MarginCalcMode.SPOT.
   *
   * @param valuationDate  the valuation date
   * @param reportingCurrency  the reporting currency
   * @param portfolioData  the portfolio data, which can be {@link PortfolioDataFile} or Strata trades
   * @param fpmlPartySelectionRegex  the regular expression used to select the party in any FpML input
   * @return the request
   */
  public static MarginCalcRequest of(
      LocalDate valuationDate,
      String reportingCurrency,
      List<? extends Bean> portfolioData,
      String fpmlPartySelectionRegex) {

    List<PortfolioDataFile> files = convertPortfolioData(portfolioData);
    return new MarginCalcRequest(
        MarginCalcRequestType.STANDARD,
        new HashSet<>(),
        MarginCalcMode.SPOT,
        valuationDate,
        false,
        reportingCurrency,
        null,
        files,
        fpmlPartySelectionRegex,
        null);
  }

  /**
   * Obtains an instance that requests a standard margin calculation.
   * <p>
   * The list of portfolio data should be either {@link PortfolioDataFile} instances
   * or Strata {@code CalculationTarget} instances, such as trades or positions.
   *
   * @param valuationDate  the valuation date
   * @param reportingCurrency  the reporting currency
   * @param mode  the mode of the calculation
   * @param portfolioData  the portfolio data, which can be {@link PortfolioDataFile} or Strata trades
   * @param fpmlPartySelectionRegex  the regular expression used to select the party in any FpML input
   * @return the request
   */
  public static MarginCalcRequest of(
      LocalDate valuationDate,
      String reportingCurrency,
      MarginCalcMode mode,
      List<? extends Bean> portfolioData,
      String fpmlPartySelectionRegex) {

    List<PortfolioDataFile> files = convertPortfolioData(portfolioData);
    return new MarginCalcRequest(
        MarginCalcRequestType.STANDARD,
        new HashSet<>(),
        mode,
        valuationDate,
        false,
        reportingCurrency,
        null,
        files,
        fpmlPartySelectionRegex,
        null);
  }

  /**
   * Obtains an instance that requests a standard margin calculation.
   * <p>
   * The list of portfolio data should be either {@link PortfolioDataFile} instances
   * or Strata {@code CalculationTarget} instances, such as trades or positions.
   * Defaults the {@link MarginCalcMode} to MarginCalcMode.SPOT.
   *
   * @param valuationDate  the valuation date
   * @param reportingCurrency  the reporting currency
   * @param portfolioData  the portfolio data, which can be {@link PortfolioDataFile} or Strata trades
   * @return the request
   */
  public static MarginCalcRequest of(
      LocalDate valuationDate,
      String reportingCurrency,
      List<? extends Bean> portfolioData) {

    List<PortfolioDataFile> files = convertPortfolioData(portfolioData);
    return new MarginCalcRequest(
        MarginCalcRequestType.STANDARD,
        new HashSet<>(),
        MarginCalcMode.SPOT,
        valuationDate,
        false,
        reportingCurrency,
        null,
        files,
        null,
        null);
  }

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance that requests a margin calculation.
   * <p>
   * The list of portfolio data should be either {@link PortfolioDataFile} instances
   * or Strata {@code CalculationTarget} instances, such as trades or positions.
   *
   * @param valuationDate  the valuation date
   * @param reportingCurrency  the reporting currency
   * @param mode  the mode of the calculation
   * @param portfolioData  the portfolio data, which can be {@link PortfolioDataFile} or Strata trades
   * @param type  the type of request to perform
   * @param applyClientModifier  whether to apply the client modifier
   * @return the request
   * @deprecated Use the builder
   */
  @Deprecated
  public static MarginCalcRequest of(
      LocalDate valuationDate,
      String reportingCurrency,
      MarginCalcMode mode,
      List<? extends Bean> portfolioData,
      MarginCalcRequestType type,
      boolean applyClientModifier) {

    List<PortfolioDataFile> files = convertPortfolioData(portfolioData);
    return new MarginCalcRequest(
        type,
        new HashSet<>(),
        mode,
        valuationDate,
        applyClientModifier,
        reportingCurrency,
        null,
        files,
        null,
        null);
  }

  /**
   * Obtains an instance that requests a margin calculation.
   * <p>
   * The list of portfolio data should be either {@link PortfolioDataFile} instances
   * or Strata {@code CalculationTarget} instances, such as trades or positions.
   * Defaults the {@link MarginCalcMode} to MarginCalcMode.SPOT.
   *
   * @param valuationDate  the valuation date
   * @param reportingCurrency  the reporting currency
   * @param portfolioData  the portfolio data, which can be {@link PortfolioDataFile} or Strata trades
   * @param type  the type of request to perform
   * @param applyClientModifier  whether to apply the client modifier
   * @return the request
   * @deprecated Use the builder
   */
  @Deprecated
  public static MarginCalcRequest of(
      LocalDate valuationDate,
      String reportingCurrency,
      List<? extends Bean> portfolioData,
      MarginCalcRequestType type,
      boolean applyClientModifier) {

    List<PortfolioDataFile> files = convertPortfolioData(portfolioData);
    return new MarginCalcRequest(
        type,
        new HashSet<>(),
        MarginCalcMode.SPOT,
        valuationDate,
        applyClientModifier,
        reportingCurrency,
        null,
        files,
        null,
        null);
  }

  private static List<PortfolioDataFile> convertPortfolioData(List<? extends Bean> portfolioData) {
    return portfolioData.stream()
        .map(PortfolioDataFile::of)
        .collect(toList());
  }

  @ImmutableDefaults
  private static void applyDefaults(Builder builder) {
    builder.mode = MarginCalcMode.SPOT;
  }

  @ImmutableConstructor
  private MarginCalcRequest(
      MarginCalcRequestType type,
      Set<MarginCalcType> calculationTypes,
      MarginCalcMode mode,
      LocalDate valuationDate,
      boolean applyClientMultiplier,
      String reportingCurrency,
      String calculationCurrency,
      List<PortfolioDataFile> portfolioData,
      String fpmlPartySelectionRegex,
      String portfolioOwnerCode) {
    JodaBeanUtils.notNull(calculationTypes, "calculationTypes");
    JodaBeanUtils.notNull(mode, "mode");
    JodaBeanUtils.notNull(valuationDate, "valuationDate");
    JodaBeanUtils.notNull(reportingCurrency, "reportingCurrency");
    JodaBeanUtils.notNull(portfolioData, "portfolioData");

    // ensure that the type field is always null, this approach means that it will still have
    // a builder method, but the value of the field will not be sent to the server
    this.type = null;
    // build set of calculation types, allowing that old type might be null
    HashSet<MarginCalcType> types = new HashSet<>(calculationTypes);
    if (type != null) {
      types.addAll(type.toCalculationTypes());
    }
    this.calculationTypes = Collections.unmodifiableSet(types);
    this.mode = mode;
    this.valuationDate = valuationDate;
    this.applyClientMultiplier = applyClientMultiplier;
    this.reportingCurrency = reportingCurrency;
    this.calculationCurrency = calculationCurrency;
    this.portfolioData = Collections.unmodifiableList(new ArrayList<>(portfolioData));
    this.fpmlPartySelectionRegex = fpmlPartySelectionRegex;
    this.portfolioOwnerCode = portfolioOwnerCode;
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the type of calculation to perform.
   * <p>
   * This has been replaced by {@link #getCalculationTypes()}, which provides
   * more control and more features.
   * If {@code PARSE_INPUTS} or {@code FULL} is set, the calculation types will include {@code PORTFOLIO_SUMMARY}.
   * If {@code STANDARD} or {@code FULL} is set, the calculation types will include {@code MARGIN}.
   * 
   * @return the type
   * @deprecated Use {@link #getCalculationTypes()} instead
   */
  @Deprecated
  public MarginCalcRequestType getType() {
    // this is provided to retain backwards compatibility of the client library
    // if the types contains neither MARGIN nor PORTFOLIO_SUMMARY then the caller
    // must be using the newer form of the API, but we have to return a value to avoid NPE
    boolean margin = calculationTypes.contains(MarginCalcType.MARGIN);
    boolean summary = calculationTypes.contains(MarginCalcType.PORTFOLIO_SUMMARY);
    if (margin) {
      return summary ? MarginCalcRequestType.FULL : MarginCalcRequestType.STANDARD;
    } else {
      return summary ? MarginCalcRequestType.PARSE_INPUTS : MarginCalcRequestType.STANDARD;
    }
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code MarginCalcRequest}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return MarginCalcRequest.Meta.INSTANCE;
  }

  static {
    MetaBean.register(MarginCalcRequest.Meta.INSTANCE);
  }

  /**
   * Returns a builder used to create an instance of the bean.
   * @return the builder, not null
   */
  public static MarginCalcRequest.Builder builder() {
    return new MarginCalcRequest.Builder();
  }

  @Override
  public MetaBean metaBean() {
    return MarginCalcRequest.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the types of information to include in the output.
   * <p>
   * If an empty set is passed in, the output type {@link MarginCalcType#MARGIN MARGIN} will be used.
   * @return the value of the property, not null
   */
  public Set<MarginCalcType> getCalculationTypes() {
    return calculationTypes;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the mode of the calculation, defaulted to {@code SPOT}.
   * @return the value of the property, not null
   */
  public MarginCalcMode getMode() {
    return mode;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the valuation date for which the portfolio will be processed.
   * @return the value of the property, not null
   */
  public LocalDate getValuationDate() {
    return valuationDate;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets whether to apply the client multiplier, default false.
   * @return the value of the property
   */
  public boolean isApplyClientMultiplier() {
    return applyClientMultiplier;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the currency that the result is reported in, as an ISO 4217 three letter currency code.
   * @return the value of the property, not null
   */
  public String getReportingCurrency() {
    return reportingCurrency;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the optional currency that the calculation is performed in, as an ISO 4217 three letter currency code.
   * If omitted, the calculation currency will be inferred from the reportingCurrency.
   * @return the optional value of the property, not null
   */
  public Optional<String> getCalculationCurrency() {
    return Optional.ofNullable(calculationCurrency);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the portfolio data, where each entry typically represents a CSV, TSV or XML file.
   * @return the value of the property, not null
   */
  public List<PortfolioDataFile> getPortfolioData() {
    return portfolioData;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the regular expression used to select the party in any FpML input.
   * The regular expression is matched against the content of the {@code partyId} elements.
   * If this is not specified, FpML cannot be parsed.
   * @return the optional value of the property, not null
   */
  public Optional<String> getFpmlPartySelectionRegex() {
    return Optional.ofNullable(fpmlPartySelectionRegex);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets to have self-referencing margin calculated correctly, we need to pass in (if specified) the clearing member code.
   * @return the optional value of the property, not null
   */
  public Optional<String> getPortfolioOwnerCode() {
    return Optional.ofNullable(portfolioOwnerCode);
  }

  //-----------------------------------------------------------------------
  /**
   * Returns a builder that allows this bean to be mutated.
   * @return the mutable builder, not null
   */
  public Builder toBuilder() {
    return new Builder(this);
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      MarginCalcRequest other = (MarginCalcRequest) obj;
      return JodaBeanUtils.equal(type, other.type) &&
          JodaBeanUtils.equal(calculationTypes, other.calculationTypes) &&
          JodaBeanUtils.equal(mode, other.mode) &&
          JodaBeanUtils.equal(valuationDate, other.valuationDate) &&
          (applyClientMultiplier == other.applyClientMultiplier) &&
          JodaBeanUtils.equal(reportingCurrency, other.reportingCurrency) &&
          JodaBeanUtils.equal(calculationCurrency, other.calculationCurrency) &&
          JodaBeanUtils.equal(portfolioData, other.portfolioData) &&
          JodaBeanUtils.equal(fpmlPartySelectionRegex, other.fpmlPartySelectionRegex) &&
          JodaBeanUtils.equal(portfolioOwnerCode, other.portfolioOwnerCode);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(type);
    hash = hash * 31 + JodaBeanUtils.hashCode(calculationTypes);
    hash = hash * 31 + JodaBeanUtils.hashCode(mode);
    hash = hash * 31 + JodaBeanUtils.hashCode(valuationDate);
    hash = hash * 31 + JodaBeanUtils.hashCode(applyClientMultiplier);
    hash = hash * 31 + JodaBeanUtils.hashCode(reportingCurrency);
    hash = hash * 31 + JodaBeanUtils.hashCode(calculationCurrency);
    hash = hash * 31 + JodaBeanUtils.hashCode(portfolioData);
    hash = hash * 31 + JodaBeanUtils.hashCode(fpmlPartySelectionRegex);
    hash = hash * 31 + JodaBeanUtils.hashCode(portfolioOwnerCode);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(320);
    buf.append("MarginCalcRequest{");
    buf.append("calculationTypes").append('=').append(JodaBeanUtils.toString(calculationTypes)).append(',').append(' ');
    buf.append("mode").append('=').append(JodaBeanUtils.toString(mode)).append(',').append(' ');
    buf.append("valuationDate").append('=').append(JodaBeanUtils.toString(valuationDate)).append(',').append(' ');
    buf.append("applyClientMultiplier").append('=').append(JodaBeanUtils.toString(applyClientMultiplier)).append(',').append(' ');
    buf.append("reportingCurrency").append('=').append(JodaBeanUtils.toString(reportingCurrency)).append(',').append(' ');
    buf.append("calculationCurrency").append('=').append(JodaBeanUtils.toString(calculationCurrency)).append(',').append(' ');
    buf.append("portfolioData").append('=').append(JodaBeanUtils.toString(portfolioData)).append(',').append(' ');
    buf.append("fpmlPartySelectionRegex").append('=').append(JodaBeanUtils.toString(fpmlPartySelectionRegex)).append(',').append(' ');
    buf.append("portfolioOwnerCode").append('=').append(JodaBeanUtils.toString(portfolioOwnerCode));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code MarginCalcRequest}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code type} property.
     */
    private final MetaProperty<MarginCalcRequestType> type = DirectMetaProperty.ofImmutable(
        this, "type", MarginCalcRequest.class, MarginCalcRequestType.class);
    /**
     * The meta-property for the {@code calculationTypes} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<Set<MarginCalcType>> calculationTypes = DirectMetaProperty.ofImmutable(
        this, "calculationTypes", MarginCalcRequest.class, (Class) Set.class);
    /**
     * The meta-property for the {@code mode} property.
     */
    private final MetaProperty<MarginCalcMode> mode = DirectMetaProperty.ofImmutable(
        this, "mode", MarginCalcRequest.class, MarginCalcMode.class);
    /**
     * The meta-property for the {@code valuationDate} property.
     */
    private final MetaProperty<LocalDate> valuationDate = DirectMetaProperty.ofImmutable(
        this, "valuationDate", MarginCalcRequest.class, LocalDate.class);
    /**
     * The meta-property for the {@code applyClientMultiplier} property.
     */
    private final MetaProperty<Boolean> applyClientMultiplier = DirectMetaProperty.ofImmutable(
        this, "applyClientMultiplier", MarginCalcRequest.class, Boolean.TYPE);
    /**
     * The meta-property for the {@code reportingCurrency} property.
     */
    private final MetaProperty<String> reportingCurrency = DirectMetaProperty.ofImmutable(
        this, "reportingCurrency", MarginCalcRequest.class, String.class);
    /**
     * The meta-property for the {@code calculationCurrency} property.
     */
    private final MetaProperty<String> calculationCurrency = DirectMetaProperty.ofImmutable(
        this, "calculationCurrency", MarginCalcRequest.class, String.class);
    /**
     * The meta-property for the {@code portfolioData} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<PortfolioDataFile>> portfolioData = DirectMetaProperty.ofImmutable(
        this, "portfolioData", MarginCalcRequest.class, (Class) List.class);
    /**
     * The meta-property for the {@code fpmlPartySelectionRegex} property.
     */
    private final MetaProperty<String> fpmlPartySelectionRegex = DirectMetaProperty.ofImmutable(
        this, "fpmlPartySelectionRegex", MarginCalcRequest.class, String.class);
    /**
     * The meta-property for the {@code portfolioOwnerCode} property.
     */
    private final MetaProperty<String> portfolioOwnerCode = DirectMetaProperty.ofImmutable(
        this, "portfolioOwnerCode", MarginCalcRequest.class, String.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "type",
        "calculationTypes",
        "mode",
        "valuationDate",
        "applyClientMultiplier",
        "reportingCurrency",
        "calculationCurrency",
        "portfolioData",
        "fpmlPartySelectionRegex",
        "portfolioOwnerCode");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 3575610:  // type
          return type;
        case 755457840:  // calculationTypes
          return calculationTypes;
        case 3357091:  // mode
          return mode;
        case 113107279:  // valuationDate
          return valuationDate;
        case 1555658618:  // applyClientMultiplier
          return applyClientMultiplier;
        case -1287844769:  // reportingCurrency
          return reportingCurrency;
        case 1466784250:  // calculationCurrency
          return calculationCurrency;
        case -689339118:  // portfolioData
          return portfolioData;
        case 527038456:  // fpmlPartySelectionRegex
          return fpmlPartySelectionRegex;
        case 1108872920:  // portfolioOwnerCode
          return portfolioOwnerCode;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public MarginCalcRequest.Builder builder() {
      return new MarginCalcRequest.Builder();
    }

    @Override
    public Class<? extends MarginCalcRequest> beanType() {
      return MarginCalcRequest.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 3575610:  // type
          return ((MarginCalcRequest) bean).type;
        case 755457840:  // calculationTypes
          return ((MarginCalcRequest) bean).getCalculationTypes();
        case 3357091:  // mode
          return ((MarginCalcRequest) bean).getMode();
        case 113107279:  // valuationDate
          return ((MarginCalcRequest) bean).getValuationDate();
        case 1555658618:  // applyClientMultiplier
          return ((MarginCalcRequest) bean).isApplyClientMultiplier();
        case -1287844769:  // reportingCurrency
          return ((MarginCalcRequest) bean).getReportingCurrency();
        case 1466784250:  // calculationCurrency
          return ((MarginCalcRequest) bean).calculationCurrency;
        case -689339118:  // portfolioData
          return ((MarginCalcRequest) bean).getPortfolioData();
        case 527038456:  // fpmlPartySelectionRegex
          return ((MarginCalcRequest) bean).fpmlPartySelectionRegex;
        case 1108872920:  // portfolioOwnerCode
          return ((MarginCalcRequest) bean).portfolioOwnerCode;
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code MarginCalcRequest}.
   */
  public static final class Builder extends DirectFieldsBeanBuilder<MarginCalcRequest> {

    private MarginCalcRequestType type;
    private Set<MarginCalcType> calculationTypes = Collections.emptySet();
    private MarginCalcMode mode;
    private LocalDate valuationDate;
    private boolean applyClientMultiplier;
    private String reportingCurrency;
    private String calculationCurrency;
    private List<PortfolioDataFile> portfolioData = Collections.emptyList();
    private String fpmlPartySelectionRegex;
    private String portfolioOwnerCode;

    /**
     * Restricted constructor.
     */
    private Builder() {
      applyDefaults(this);
    }

    /**
     * Restricted copy constructor.
     * @param beanToCopy  the bean to copy from, not null
     */
    private Builder(MarginCalcRequest beanToCopy) {
      this.type = beanToCopy.type;
      this.calculationTypes = new HashSet<>(beanToCopy.getCalculationTypes());
      this.mode = beanToCopy.getMode();
      this.valuationDate = beanToCopy.getValuationDate();
      this.applyClientMultiplier = beanToCopy.isApplyClientMultiplier();
      this.reportingCurrency = beanToCopy.getReportingCurrency();
      this.calculationCurrency = beanToCopy.calculationCurrency;
      this.portfolioData = new ArrayList<>(beanToCopy.getPortfolioData());
      this.fpmlPartySelectionRegex = beanToCopy.fpmlPartySelectionRegex;
      this.portfolioOwnerCode = beanToCopy.portfolioOwnerCode;
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 3575610:  // type
          return type;
        case 755457840:  // calculationTypes
          return calculationTypes;
        case 3357091:  // mode
          return mode;
        case 113107279:  // valuationDate
          return valuationDate;
        case 1555658618:  // applyClientMultiplier
          return applyClientMultiplier;
        case -1287844769:  // reportingCurrency
          return reportingCurrency;
        case 1466784250:  // calculationCurrency
          return calculationCurrency;
        case -689339118:  // portfolioData
          return portfolioData;
        case 527038456:  // fpmlPartySelectionRegex
          return fpmlPartySelectionRegex;
        case 1108872920:  // portfolioOwnerCode
          return portfolioOwnerCode;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 3575610:  // type
          this.type = (MarginCalcRequestType) newValue;
          break;
        case 755457840:  // calculationTypes
          this.calculationTypes = (Set<MarginCalcType>) newValue;
          break;
        case 3357091:  // mode
          this.mode = (MarginCalcMode) newValue;
          break;
        case 113107279:  // valuationDate
          this.valuationDate = (LocalDate) newValue;
          break;
        case 1555658618:  // applyClientMultiplier
          this.applyClientMultiplier = (Boolean) newValue;
          break;
        case -1287844769:  // reportingCurrency
          this.reportingCurrency = (String) newValue;
          break;
        case 1466784250:  // calculationCurrency
          this.calculationCurrency = (String) newValue;
          break;
        case -689339118:  // portfolioData
          this.portfolioData = (List<PortfolioDataFile>) newValue;
          break;
        case 527038456:  // fpmlPartySelectionRegex
          this.fpmlPartySelectionRegex = (String) newValue;
          break;
        case 1108872920:  // portfolioOwnerCode
          this.portfolioOwnerCode = (String) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public Builder set(MetaProperty<?> property, Object value) {
      super.set(property, value);
      return this;
    }

    @Override
    public MarginCalcRequest build() {
      return new MarginCalcRequest(
          type,
          calculationTypes,
          mode,
          valuationDate,
          applyClientMultiplier,
          reportingCurrency,
          calculationCurrency,
          portfolioData,
          fpmlPartySelectionRegex,
          portfolioOwnerCode);
    }

    //-----------------------------------------------------------------------
    /**
     * Sets the type of calculation to perform.
     * <p>
     * This has been replaced by {@link #getCalculationTypes()}, which provides
     * more control and more features.
     * If {@code PARSE_INPUTS} or {@code FULL} is set, the calculation types will include {@code PORTFOLIO_SUMMARY}.
     * If {@code STANDARD} or {@code FULL} is set, the calculation types will include {@code MARGIN}.
     * 
     * @param type  the new value
     * @return this, for chaining, not null
     * @deprecated Use {@link #getCalculationTypes()} instead
     */
    @Deprecated
    public Builder type(MarginCalcRequestType type) {
      this.type = type;
      return this;
    }

    /**
     * Sets the types of information to include in the output.
     * <p>
     * If an empty set is passed in, the output type {@link MarginCalcType#MARGIN MARGIN} will be used.
     * @param calculationTypes  the new value, not null
     * @return this, for chaining, not null
     */
    public Builder calculationTypes(Set<MarginCalcType> calculationTypes) {
      JodaBeanUtils.notNull(calculationTypes, "calculationTypes");
      this.calculationTypes = calculationTypes;
      return this;
    }

    /**
     * Sets the {@code calculationTypes} property in the builder
     * from an array of objects.
     * @param calculationTypes  the new value, not null
     * @return this, for chaining, not null
     */
    public Builder calculationTypes(MarginCalcType... calculationTypes) {
      return calculationTypes(new LinkedHashSet<MarginCalcType>(Arrays.asList(calculationTypes)));
    }

    /**
     * Sets the mode of the calculation, defaulted to {@code SPOT}.
     * @param mode  the new value, not null
     * @return this, for chaining, not null
     */
    public Builder mode(MarginCalcMode mode) {
      JodaBeanUtils.notNull(mode, "mode");
      this.mode = mode;
      return this;
    }

    /**
     * Sets the valuation date for which the portfolio will be processed.
     * @param valuationDate  the new value, not null
     * @return this, for chaining, not null
     */
    public Builder valuationDate(LocalDate valuationDate) {
      JodaBeanUtils.notNull(valuationDate, "valuationDate");
      this.valuationDate = valuationDate;
      return this;
    }

    /**
     * Sets whether to apply the client multiplier, default false.
     * @param applyClientMultiplier  the new value
     * @return this, for chaining, not null
     */
    public Builder applyClientMultiplier(boolean applyClientMultiplier) {
      this.applyClientMultiplier = applyClientMultiplier;
      return this;
    }

    /**
     * Sets the currency that the result is reported in, as an ISO 4217 three letter currency code.
     * @param reportingCurrency  the new value, not null
     * @return this, for chaining, not null
     */
    public Builder reportingCurrency(String reportingCurrency) {
      JodaBeanUtils.notNull(reportingCurrency, "reportingCurrency");
      this.reportingCurrency = reportingCurrency;
      return this;
    }

    /**
     * Sets the optional currency that the calculation is performed in, as an ISO 4217 three letter currency code.
     * If omitted, the calculation currency will be inferred from the reportingCurrency.
     * @param calculationCurrency  the new value
     * @return this, for chaining, not null
     */
    public Builder calculationCurrency(String calculationCurrency) {
      this.calculationCurrency = calculationCurrency;
      return this;
    }

    /**
     * Sets the portfolio data, where each entry typically represents a CSV, TSV or XML file.
     * @param portfolioData  the new value, not null
     * @return this, for chaining, not null
     */
    public Builder portfolioData(List<PortfolioDataFile> portfolioData) {
      JodaBeanUtils.notNull(portfolioData, "portfolioData");
      this.portfolioData = portfolioData;
      return this;
    }

    /**
     * Sets the {@code portfolioData} property in the builder
     * from an array of objects.
     * @param portfolioData  the new value, not null
     * @return this, for chaining, not null
     */
    public Builder portfolioData(PortfolioDataFile... portfolioData) {
      return portfolioData(Arrays.asList(portfolioData));
    }

    /**
     * Sets the regular expression used to select the party in any FpML input.
     * The regular expression is matched against the content of the {@code partyId} elements.
     * If this is not specified, FpML cannot be parsed.
     * @param fpmlPartySelectionRegex  the new value
     * @return this, for chaining, not null
     */
    public Builder fpmlPartySelectionRegex(String fpmlPartySelectionRegex) {
      this.fpmlPartySelectionRegex = fpmlPartySelectionRegex;
      return this;
    }

    /**
     * Sets to have self-referencing margin calculated correctly, we need to pass in (if specified) the clearing member code.
     * @param portfolioOwnerCode  the new value
     * @return this, for chaining, not null
     */
    public Builder portfolioOwnerCode(String portfolioOwnerCode) {
      this.portfolioOwnerCode = portfolioOwnerCode;
      return this;
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(320);
      buf.append("MarginCalcRequest.Builder{");
      buf.append("calculationTypes").append('=').append(JodaBeanUtils.toString(calculationTypes)).append(',').append(' ');
      buf.append("mode").append('=').append(JodaBeanUtils.toString(mode)).append(',').append(' ');
      buf.append("valuationDate").append('=').append(JodaBeanUtils.toString(valuationDate)).append(',').append(' ');
      buf.append("applyClientMultiplier").append('=').append(JodaBeanUtils.toString(applyClientMultiplier)).append(',').append(' ');
      buf.append("reportingCurrency").append('=').append(JodaBeanUtils.toString(reportingCurrency)).append(',').append(' ');
      buf.append("calculationCurrency").append('=').append(JodaBeanUtils.toString(calculationCurrency)).append(',').append(' ');
      buf.append("portfolioData").append('=').append(JodaBeanUtils.toString(portfolioData)).append(',').append(' ');
      buf.append("fpmlPartySelectionRegex").append('=').append(JodaBeanUtils.toString(fpmlPartySelectionRegex)).append(',').append(' ');
      buf.append("portfolioOwnerCode").append('=').append(JodaBeanUtils.toString(portfolioOwnerCode));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @Deprecated
public enum MarginCalcRequestType {

  /**
   * Parse and summarize the inputs, performing no margin calculation.
   * <p>
   * Portfolio summary and parsing errors will be returned.
   */
  PARSE_INPUTS,
  /**
   * Perform a standard margin calculation for the inputs.
   * <p>
   * Margin, parsing errors and calculation errors will be returned.
   */
  STANDARD,
  /**
   * Perform a full margin calculation for the inputs.
   * <p>
   * Margin, portfolio summary, parsing errors and calculation errors will be returned.
   */
  FULL;

  // converts the type to MarginCalcType
  Set<MarginCalcType> toCalculationTypes() {
    HashSet<MarginCalcType> types = new HashSet<>();
    if (this == MarginCalcRequestType.PARSE_INPUTS || this == MarginCalcRequestType.FULL) {
      types.add(MarginCalcType.PORTFOLIO_SUMMARY);
    }
    if (this == MarginCalcRequestType.STANDARD || this == MarginCalcRequestType.FULL) {
      types.add(MarginCalcType.MARGIN);
    }
    return types;
  }

} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class MarginCalcResult implements ImmutableBean {

  /**
   * The status of the calculation - PENDING or COMPLETED.
   */
  @PropertyDefinition(validate = "notNull")
  private final MarginCalcResultStatus status;
  /**
   * The types of calculation that were performed.
   * <p>
   * The types may differ from the requested calculation types if the user does not have
   * the necessary permission for the calculation, or the CCP does not support it.
   */
  @PropertyDefinition(validate = "notNull")
  private final Set<MarginCalcType> calculationTypes;
  /**
   * The mode of the calculation - SPOT or FORWARD.
   */
  @PropertyDefinition(validate = "notNull")
  private final MarginCalcMode mode;
  /**
   * The valuation date of the calculation.
   */
  @PropertyDefinition(validate = "notNull")
  private final LocalDate valuationDate;
  /**
   * The reporting currency, as an ISO 4217 three letter currency code.
   */
  @PropertyDefinition(validate = "notNull")
  private final String reportingCurrency;
  /**
   * The currency that the calculation was performed in, as an ISO 4217 three letter currency code.
   */
  @PropertyDefinition(validate = "notNull")
  private final String calculationCurrency;
  /**
   * Whether to apply the client multiplier.
   */
  @PropertyDefinition(validate = "notNull")
  private final boolean applyClientMultiplier;
  /**
   * The summary of the portfolio items, may be empty.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<PortfolioItemSummary> portfolioItems;
  /**
   * The result of the margin calculation
   */
  @PropertyDefinition(get = "optional")
  private final MarginSummary margin;
  /**
   * The detailed breakdown of the margin calculation.
   * The structure varies by CCP.
   */
  @PropertyDefinition(get = "optional")
  private final MarginDetail marginDetail;
  /**
   * The valuation of the trades, including present value, delta and gamma results.
   * Sensitivity-based inputs are not valued.
   */
  @PropertyDefinition(get = "optional")
  private final TradeValuations tradeValuations;
  /**
   * The list of failures that occurred, may be empty.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<MarginError> failures;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance.
   * @param status  the value of the property, not null
   * @param type  the value of the property, not null
   * @param mode  the value of the property, not null
   * @param valuationDate  the value of the property, not null
   * @param reportingCurrency  the value of the property, not null
   * @param applyClientMultiplier  the value of the property, not null
   * @param portfolioItems  the value of the property, not null
   * @param margin  the value of the property
   * @param failures  the value of the property, not null
   * @return the instance
   * @deprecated Use the 12-arg version of this method
   *   (it is intended that the SDK creates instances of this class, your code should only create instances in tests)
   */
  @Deprecated
  public static MarginCalcResult of(
      MarginCalcResultStatus status,
      MarginCalcRequestType type,
      MarginCalcMode mode,
      LocalDate valuationDate,
      String reportingCurrency,
      boolean applyClientMultiplier,
      List<PortfolioItemSummary> portfolioItems,
      MarginSummary margin,
      List<MarginError> failures) {

    return new MarginCalcResult(
        status,
        type.toCalculationTypes(),
        mode,
        valuationDate,
        reportingCurrency,
        reportingCurrency,
        applyClientMultiplier,
        portfolioItems,
        margin,
        null,
        null,
        failures);
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the type of the calculation request.
   * 
   * @return the type
   * @deprecated Use {@link #getCalculationTypes()} instead
   */
  @Deprecated
  public MarginCalcRequestType getType() {
    // this is provided to retain backwards compatibility of the client library
    // if the types contains neither MARGIN nor PORTFOLIO_SUMMARY then the caller
    // must be using the newer form of the API, but we have to return a value to avoid NPE
    boolean margin = calculationTypes.contains(MarginCalcType.MARGIN);
    boolean summary = calculationTypes.contains(MarginCalcType.PORTFOLIO_SUMMARY);
    if (margin) {
      return summary ? MarginCalcRequestType.FULL : MarginCalcRequestType.STANDARD;
    } else {
      return summary ? MarginCalcRequestType.PARSE_INPUTS : MarginCalcRequestType.STANDARD;
    }
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code MarginCalcResult}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return MarginCalcResult.Meta.INSTANCE;
  }

  static {
    MetaBean.register(MarginCalcResult.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param status  the value of the property, not null
   * @param calculationTypes  the value of the property, not null
   * @param mode  the value of the property, not null
   * @param valuationDate  the value of the property, not null
   * @param reportingCurrency  the value of the property, not null
   * @param calculationCurrency  the value of the property, not null
   * @param applyClientMultiplier  the value of the property, not null
   * @param portfolioItems  the value of the property, not null
   * @param margin  the value of the property
   * @param marginDetail  the value of the property
   * @param tradeValuations  the value of the property
   * @param failures  the value of the property, not null
   * @return the instance
   */
  public static MarginCalcResult of(
      MarginCalcResultStatus status,
      Set<MarginCalcType> calculationTypes,
      MarginCalcMode mode,
      LocalDate valuationDate,
      String reportingCurrency,
      String calculationCurrency,
      boolean applyClientMultiplier,
      List<PortfolioItemSummary> portfolioItems,
      MarginSummary margin,
      MarginDetail marginDetail,
      TradeValuations tradeValuations,
      List<MarginError> failures) {
    return new MarginCalcResult(
      status,
      calculationTypes,
      mode,
      valuationDate,
      reportingCurrency,
      calculationCurrency,
      applyClientMultiplier,
      portfolioItems,
      margin,
      marginDetail,
      tradeValuations,
      failures);
  }

  private MarginCalcResult(
      MarginCalcResultStatus status,
      Set<MarginCalcType> calculationTypes,
      MarginCalcMode mode,
      LocalDate valuationDate,
      String reportingCurrency,
      String calculationCurrency,
      boolean applyClientMultiplier,
      List<PortfolioItemSummary> portfolioItems,
      MarginSummary margin,
      MarginDetail marginDetail,
      TradeValuations tradeValuations,
      List<MarginError> failures) {
    JodaBeanUtils.notNull(status, "status");
    JodaBeanUtils.notNull(calculationTypes, "calculationTypes");
    JodaBeanUtils.notNull(mode, "mode");
    JodaBeanUtils.notNull(valuationDate, "valuationDate");
    JodaBeanUtils.notNull(reportingCurrency, "reportingCurrency");
    JodaBeanUtils.notNull(calculationCurrency, "calculationCurrency");
    JodaBeanUtils.notNull(applyClientMultiplier, "applyClientMultiplier");
    JodaBeanUtils.notNull(portfolioItems, "portfolioItems");
    JodaBeanUtils.notNull(failures, "failures");
    this.status = status;
    this.calculationTypes = Collections.unmodifiableSet(new HashSet<>(calculationTypes));
    this.mode = mode;
    this.valuationDate = valuationDate;
    this.reportingCurrency = reportingCurrency;
    this.calculationCurrency = calculationCurrency;
    this.applyClientMultiplier = applyClientMultiplier;
    this.portfolioItems = Collections.unmodifiableList(new ArrayList<>(portfolioItems));
    this.margin = margin;
    this.marginDetail = marginDetail;
    this.tradeValuations = tradeValuations;
    this.failures = Collections.unmodifiableList(new ArrayList<>(failures));
  }

  @Override
  public MetaBean metaBean() {
    return MarginCalcResult.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the status of the calculation - PENDING or COMPLETED.
   * @return the value of the property, not null
   */
  public MarginCalcResultStatus getStatus() {
    return status;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the types of calculation that were performed.
   * <p>
   * The types may differ from the requested calculation types if the user does not have
   * the necessary permission for the calculation, or the CCP does not support it.
   * @return the value of the property, not null
   */
  public Set<MarginCalcType> getCalculationTypes() {
    return calculationTypes;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the mode of the calculation - SPOT or FORWARD.
   * @return the value of the property, not null
   */
  public MarginCalcMode getMode() {
    return mode;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the valuation date of the calculation.
   * @return the value of the property, not null
   */
  public LocalDate getValuationDate() {
    return valuationDate;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the reporting currency, as an ISO 4217 three letter currency code.
   * @return the value of the property, not null
   */
  public String getReportingCurrency() {
    return reportingCurrency;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the currency that the calculation was performed in, as an ISO 4217 three letter currency code.
   * @return the value of the property, not null
   */
  public String getCalculationCurrency() {
    return calculationCurrency;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets whether to apply the client multiplier.
   * @return the value of the property, not null
   */
  public boolean isApplyClientMultiplier() {
    return applyClientMultiplier;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the summary of the portfolio items, may be empty.
   * @return the value of the property, not null
   */
  public List<PortfolioItemSummary> getPortfolioItems() {
    return portfolioItems;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the result of the margin calculation
   * @return the optional value of the property, not null
   */
  public Optional<MarginSummary> getMargin() {
    return Optional.ofNullable(margin);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the detailed breakdown of the margin calculation.
   * The structure varies by CCP.
   * @return the optional value of the property, not null
   */
  public Optional<MarginDetail> getMarginDetail() {
    return Optional.ofNullable(marginDetail);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the valuation of the trades, including present value, delta and gamma results.
   * Sensitivity-based inputs are not valued.
   * @return the optional value of the property, not null
   */
  public Optional<TradeValuations> getTradeValuations() {
    return Optional.ofNullable(tradeValuations);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of failures that occurred, may be empty.
   * @return the value of the property, not null
   */
  public List<MarginError> getFailures() {
    return failures;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      MarginCalcResult other = (MarginCalcResult) obj;
      return JodaBeanUtils.equal(status, other.status) &&
          JodaBeanUtils.equal(calculationTypes, other.calculationTypes) &&
          JodaBeanUtils.equal(mode, other.mode) &&
          JodaBeanUtils.equal(valuationDate, other.valuationDate) &&
          JodaBeanUtils.equal(reportingCurrency, other.reportingCurrency) &&
          JodaBeanUtils.equal(calculationCurrency, other.calculationCurrency) &&
          (applyClientMultiplier == other.applyClientMultiplier) &&
          JodaBeanUtils.equal(portfolioItems, other.portfolioItems) &&
          JodaBeanUtils.equal(margin, other.margin) &&
          JodaBeanUtils.equal(marginDetail, other.marginDetail) &&
          JodaBeanUtils.equal(tradeValuations, other.tradeValuations) &&
          JodaBeanUtils.equal(failures, other.failures);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(status);
    hash = hash * 31 + JodaBeanUtils.hashCode(calculationTypes);
    hash = hash * 31 + JodaBeanUtils.hashCode(mode);
    hash = hash * 31 + JodaBeanUtils.hashCode(valuationDate);
    hash = hash * 31 + JodaBeanUtils.hashCode(reportingCurrency);
    hash = hash * 31 + JodaBeanUtils.hashCode(calculationCurrency);
    hash = hash * 31 + JodaBeanUtils.hashCode(applyClientMultiplier);
    hash = hash * 31 + JodaBeanUtils.hashCode(portfolioItems);
    hash = hash * 31 + JodaBeanUtils.hashCode(margin);
    hash = hash * 31 + JodaBeanUtils.hashCode(marginDetail);
    hash = hash * 31 + JodaBeanUtils.hashCode(tradeValuations);
    hash = hash * 31 + JodaBeanUtils.hashCode(failures);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(416);
    buf.append("MarginCalcResult{");
    buf.append("status").append('=').append(JodaBeanUtils.toString(status)).append(',').append(' ');
    buf.append("calculationTypes").append('=').append(JodaBeanUtils.toString(calculationTypes)).append(',').append(' ');
    buf.append("mode").append('=').append(JodaBeanUtils.toString(mode)).append(',').append(' ');
    buf.append("valuationDate").append('=').append(JodaBeanUtils.toString(valuationDate)).append(',').append(' ');
    buf.append("reportingCurrency").append('=').append(JodaBeanUtils.toString(reportingCurrency)).append(',').append(' ');
    buf.append("calculationCurrency").append('=').append(JodaBeanUtils.toString(calculationCurrency)).append(',').append(' ');
    buf.append("applyClientMultiplier").append('=').append(JodaBeanUtils.toString(applyClientMultiplier)).append(',').append(' ');
    buf.append("portfolioItems").append('=').append(JodaBeanUtils.toString(portfolioItems)).append(',').append(' ');
    buf.append("margin").append('=').append(JodaBeanUtils.toString(margin)).append(',').append(' ');
    buf.append("marginDetail").append('=').append(JodaBeanUtils.toString(marginDetail)).append(',').append(' ');
    buf.append("tradeValuations").append('=').append(JodaBeanUtils.toString(tradeValuations)).append(',').append(' ');
    buf.append("failures").append('=').append(JodaBeanUtils.toString(failures));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code MarginCalcResult}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code status} property.
     */
    private final MetaProperty<MarginCalcResultStatus> status = DirectMetaProperty.ofImmutable(
        this, "status", MarginCalcResult.class, MarginCalcResultStatus.class);
    /**
     * The meta-property for the {@code calculationTypes} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<Set<MarginCalcType>> calculationTypes = DirectMetaProperty.ofImmutable(
        this, "calculationTypes", MarginCalcResult.class, (Class) Set.class);
    /**
     * The meta-property for the {@code mode} property.
     */
    private final MetaProperty<MarginCalcMode> mode = DirectMetaProperty.ofImmutable(
        this, "mode", MarginCalcResult.class, MarginCalcMode.class);
    /**
     * The meta-property for the {@code valuationDate} property.
     */
    private final MetaProperty<LocalDate> valuationDate = DirectMetaProperty.ofImmutable(
        this, "valuationDate", MarginCalcResult.class, LocalDate.class);
    /**
     * The meta-property for the {@code reportingCurrency} property.
     */
    private final MetaProperty<String> reportingCurrency = DirectMetaProperty.ofImmutable(
        this, "reportingCurrency", MarginCalcResult.class, String.class);
    /**
     * The meta-property for the {@code calculationCurrency} property.
     */
    private final MetaProperty<String> calculationCurrency = DirectMetaProperty.ofImmutable(
        this, "calculationCurrency", MarginCalcResult.class, String.class);
    /**
     * The meta-property for the {@code applyClientMultiplier} property.
     */
    private final MetaProperty<Boolean> applyClientMultiplier = DirectMetaProperty.ofImmutable(
        this, "applyClientMultiplier", MarginCalcResult.class, Boolean.TYPE);
    /**
     * The meta-property for the {@code portfolioItems} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<PortfolioItemSummary>> portfolioItems = DirectMetaProperty.ofImmutable(
        this, "portfolioItems", MarginCalcResult.class, (Class) List.class);
    /**
     * The meta-property for the {@code margin} property.
     */
    private final MetaProperty<MarginSummary> margin = DirectMetaProperty.ofImmutable(
        this, "margin", MarginCalcResult.class, MarginSummary.class);
    /**
     * The meta-property for the {@code marginDetail} property.
     */
    private final MetaProperty<MarginDetail> marginDetail = DirectMetaProperty.ofImmutable(
        this, "marginDetail", MarginCalcResult.class, MarginDetail.class);
    /**
     * The meta-property for the {@code tradeValuations} property.
     */
    private final MetaProperty<TradeValuations> tradeValuations = DirectMetaProperty.ofImmutable(
        this, "tradeValuations", MarginCalcResult.class, TradeValuations.class);
    /**
     * The meta-property for the {@code failures} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<MarginError>> failures = DirectMetaProperty.ofImmutable(
        this, "failures", MarginCalcResult.class, (Class) List.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "status",
        "calculationTypes",
        "mode",
        "valuationDate",
        "reportingCurrency",
        "calculationCurrency",
        "applyClientMultiplier",
        "portfolioItems",
        "margin",
        "marginDetail",
        "tradeValuations",
        "failures");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case -892481550:  // status
          return status;
        case 755457840:  // calculationTypes
          return calculationTypes;
        case 3357091:  // mode
          return mode;
        case 113107279:  // valuationDate
          return valuationDate;
        case -1287844769:  // reportingCurrency
          return reportingCurrency;
        case 1466784250:  // calculationCurrency
          return calculationCurrency;
        case 1555658618:  // applyClientMultiplier
          return applyClientMultiplier;
        case 110493528:  // portfolioItems
          return portfolioItems;
        case -1081309778:  // margin
          return margin;
        case -241168481:  // marginDetail
          return marginDetail;
        case 1449179926:  // tradeValuations
          return tradeValuations;
        case 675938345:  // failures
          return failures;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends MarginCalcResult> builder() {
      return new MarginCalcResult.Builder();
    }

    @Override
    public Class<? extends MarginCalcResult> beanType() {
      return MarginCalcResult.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -892481550:  // status
          return ((MarginCalcResult) bean).getStatus();
        case 755457840:  // calculationTypes
          return ((MarginCalcResult) bean).getCalculationTypes();
        case 3357091:  // mode
          return ((MarginCalcResult) bean).getMode();
        case 113107279:  // valuationDate
          return ((MarginCalcResult) bean).getValuationDate();
        case -1287844769:  // reportingCurrency
          return ((MarginCalcResult) bean).getReportingCurrency();
        case 1466784250:  // calculationCurrency
          return ((MarginCalcResult) bean).getCalculationCurrency();
        case 1555658618:  // applyClientMultiplier
          return ((MarginCalcResult) bean).isApplyClientMultiplier();
        case 110493528:  // portfolioItems
          return ((MarginCalcResult) bean).getPortfolioItems();
        case -1081309778:  // margin
          return ((MarginCalcResult) bean).margin;
        case -241168481:  // marginDetail
          return ((MarginCalcResult) bean).marginDetail;
        case 1449179926:  // tradeValuations
          return ((MarginCalcResult) bean).tradeValuations;
        case 675938345:  // failures
          return ((MarginCalcResult) bean).getFailures();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code MarginCalcResult}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<MarginCalcResult> {

    private MarginCalcResultStatus status;
    private Set<MarginCalcType> calculationTypes = Collections.emptySet();
    private MarginCalcMode mode;
    private LocalDate valuationDate;
    private String reportingCurrency;
    private String calculationCurrency;
    private boolean applyClientMultiplier;
    private List<PortfolioItemSummary> portfolioItems = Collections.emptyList();
    private MarginSummary margin;
    private MarginDetail marginDetail;
    private TradeValuations tradeValuations;
    private List<MarginError> failures = Collections.emptyList();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case -892481550:  // status
          return status;
        case 755457840:  // calculationTypes
          return calculationTypes;
        case 3357091:  // mode
          return mode;
        case 113107279:  // valuationDate
          return valuationDate;
        case -1287844769:  // reportingCurrency
          return reportingCurrency;
        case 1466784250:  // calculationCurrency
          return calculationCurrency;
        case 1555658618:  // applyClientMultiplier
          return applyClientMultiplier;
        case 110493528:  // portfolioItems
          return portfolioItems;
        case -1081309778:  // margin
          return margin;
        case -241168481:  // marginDetail
          return marginDetail;
        case 1449179926:  // tradeValuations
          return tradeValuations;
        case 675938345:  // failures
          return failures;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case -892481550:  // status
          this.status = (MarginCalcResultStatus) newValue;
          break;
        case 755457840:  // calculationTypes
          this.calculationTypes = (Set<MarginCalcType>) newValue;
          break;
        case 3357091:  // mode
          this.mode = (MarginCalcMode) newValue;
          break;
        case 113107279:  // valuationDate
          this.valuationDate = (LocalDate) newValue;
          break;
        case -1287844769:  // reportingCurrency
          this.reportingCurrency = (String) newValue;
          break;
        case 1466784250:  // calculationCurrency
          this.calculationCurrency = (String) newValue;
          break;
        case 1555658618:  // applyClientMultiplier
          this.applyClientMultiplier = (Boolean) newValue;
          break;
        case 110493528:  // portfolioItems
          this.portfolioItems = (List<PortfolioItemSummary>) newValue;
          break;
        case -1081309778:  // margin
          this.margin = (MarginSummary) newValue;
          break;
        case -241168481:  // marginDetail
          this.marginDetail = (MarginDetail) newValue;
          break;
        case 1449179926:  // tradeValuations
          this.tradeValuations = (TradeValuations) newValue;
          break;
        case 675938345:  // failures
          this.failures = (List<MarginError>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public MarginCalcResult build() {
      return new MarginCalcResult(
          status,
          calculationTypes,
          mode,
          valuationDate,
          reportingCurrency,
          calculationCurrency,
          applyClientMultiplier,
          portfolioItems,
          margin,
          marginDetail,
          tradeValuations,
          failures);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(416);
      buf.append("MarginCalcResult.Builder{");
      buf.append("status").append('=').append(JodaBeanUtils.toString(status)).append(',').append(' ');
      buf.append("calculationTypes").append('=').append(JodaBeanUtils.toString(calculationTypes)).append(',').append(' ');
      buf.append("mode").append('=').append(JodaBeanUtils.toString(mode)).append(',').append(' ');
      buf.append("valuationDate").append('=').append(JodaBeanUtils.toString(valuationDate)).append(',').append(' ');
      buf.append("reportingCurrency").append('=').append(JodaBeanUtils.toString(reportingCurrency)).append(',').append(' ');
      buf.append("calculationCurrency").append('=').append(JodaBeanUtils.toString(calculationCurrency)).append(',').append(' ');
      buf.append("applyClientMultiplier").append('=').append(JodaBeanUtils.toString(applyClientMultiplier)).append(',').append(' ');
      buf.append("portfolioItems").append('=').append(JodaBeanUtils.toString(portfolioItems)).append(',').append(' ');
      buf.append("margin").append('=').append(JodaBeanUtils.toString(margin)).append(',').append(' ');
      buf.append("marginDetail").append('=').append(JodaBeanUtils.toString(marginDetail)).append(',').append(' ');
      buf.append("tradeValuations").append('=').append(JodaBeanUtils.toString(tradeValuations)).append(',').append(' ');
      buf.append("failures").append('=').append(JodaBeanUtils.toString(failures));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} public enum MarginCalcResultStatus {

  /**
   * Calculation is pending.
   */
  PENDING,
  /**
   * Calculation has completed.
   */
  COMPLETED;

} public enum MarginCalcType {
  // this is a fixed list, which might cause a problem in deserialization if the server sends back a new value
  // but the server will only send a value back if it is requested by the client
  // since an older client won't request a newer value, also won't receive a newer value

  /**
   * Requests the portfolio summary.
   * This can be used to check that the portfolio was parsed correctly.
   */
  PORTFOLIO_SUMMARY,

  /**
   * Requests the margin.
   */
  MARGIN,

  /**
   * Requests the detailed breakdown of the margin.
   */
  MARGIN_DETAIL,

  /**
   * Requests the present value.
   */
  PRESENT_VALUE,

  /**
   * Requests the delta of the present value sensitivity.
   */
  DELTA,

  /**
   * Requests the gamma of the present value sensitivity.
   */
  GAMMA,

} public interface MarginClient {

  /**
   * Obtains an instance, specifying the invoker to use.
   * <p>
   * The {@link ServiceInvoker} provides authentication.
   *
   * @param invoker  the service invoker
   * @return the client
   */
  public static MarginClient of(ServiceInvoker invoker) {
    return InvokerMarginClient.of(invoker);
  }

  //-------------------------------------------------------------------------
  /**
   * Lists the available CCPs.
   *
   * @return the list of available CCPs
   * @throws MarginException if unable to list the CCPS
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract CcpsResult listCcps();

  /**
   * Gets information about a single CCP.
   *
   * @param ccp  the CCP to lookup
   * @return the information about the CCP
   * @throws MarginException if unable to get the information
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract CcpInfo getCcpInfo(Ccp ccp);

  /**
   * Creates a margin calculation task.
   *
   * @param ccp  the CCP to use
   * @param request  the calculation request
   * @return the calculation identifier
   * @throws MarginException if unable to create the calculation
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract String createCalculation(Ccp ccp, MarginCalcRequest request);

  /**
   * Gets the result of a margin calculation task.
   *
   * @param ccp  the CCP to use
   * @param calcId  the calculation identifier
   * @return the calculation result
   * @throws MarginException if unable to get the calculation
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract MarginCalcResult getCalculation(Ccp ccp, String calcId);

  /**
   * Deletes a margin calculation task.
   *
   * @param ccp  the CCP to use
   * @param calcId  the calculation identifier
   * @throws MarginException if unable to delete the calculation
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract void deleteCalculation(Ccp ccp, String calcId);

  //-------------------------------------------------------------------------
  /**
   * High-level call to submit a portfolio for parsing, validation and IM calculation.
   * <p>
   * If the thread is interrupted while this method is blocked, then a runtime exception
   * is thrown, but with the interrupt flag set.
   * For additional control, use {@link #calculateAsync(Ccp, MarginCalcRequest)}.
   *
   * @param ccp  the CCP to use
   * @param request  the calculation request
   * @return the detailed result of the calculation
   * @throws MarginException if unable to calculate
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract MarginCalcResult calculate(Ccp ccp, MarginCalcRequest request);

  /**
   * High-level call to submit a portfolio for parsing, validation and IM calculation,
   * performing the work on a background thread.
   * <p>
   * This will use the executor from the service invoker to perform the background work.
   * <p>
   * Callers should consider whether to use {@link CompletableFuture#get(long, java.util.concurrent.TimeUnit)}
   * to enforce a time out on the calculation.
   *
   * @param ccp  the CCP to use
   * @param request  the calculation request
   * @return the detailed result of the calculation, expressed via a future
   * @throws RuntimeException if unable to setup the async calculation
   */
  public abstract CompletableFuture<MarginCalcResult> calculateAsync(Ccp ccp, MarginCalcRequest request);

  //-------------------------------------------------------------------------
  /**
   * High-level call to submit a base portfolio together with an extra set of trades,
   * for parsing, validation and IM calculation.
   * <p>
   * This will return the margin summary for the base request, the combined request (base portfolio + delta portfolio),
   * and the difference between the two.
   *
   * @param ccp  the CCP to use
   * @param request  the calculation request
   * @param deltaFiles  the portfolios representing the extra trades for the what-if scenario
   * @return the detailed result of the calculation
   * @throws MarginException if unable to calculate
   * @throws UncheckedIOException if an IO error occurs
   */
  public abstract MarginWhatIfCalcResult calculateWhatIf(
      Ccp ccp,
      MarginCalcRequest request,
      List<PortfolioDataFile> deltaFiles);

} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class MarginSummary implements ImmutableBean {

  /**
   * The total margin, expressed in the reporting currency.
   */
  @PropertyDefinition
  private final double margin;
  /**
   * The CCP-specific breakdown of the initial margin.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<NamedValue> marginDetails;
  /**
   * The standardized breakdown of the initial margin.
   * <p>
   * The contents of {@link #getMarginDetails()} are CCP-specific.
   * This breakdown summarizes the values under three standardized headings.
   */
  @PropertyDefinition(validate = "notNull")
  private final MarginBreakdown breakdown;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance.
   * 
   * @param margin  the total margin
   * @param marginDetails  the margin details
   * @return the instance
   * @deprecated Use the 3-arg version of this method
   *   (it is intended that the SDK creates instances of this class, your code should only create instances in tests)
   */
  @Deprecated
  public static MarginSummary of(double margin, List<NamedValue> marginDetails) {
    return new MarginSummary(
        margin,
        marginDetails,
        MarginBreakdown.of(margin, margin, 0, 0));
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code MarginSummary}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return MarginSummary.Meta.INSTANCE;
  }

  static {
    MetaBean.register(MarginSummary.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param margin  the value of the property
   * @param marginDetails  the value of the property, not null
   * @param breakdown  the value of the property, not null
   * @return the instance
   */
  public static MarginSummary of(
      double margin,
      List<NamedValue> marginDetails,
      MarginBreakdown breakdown) {
    return new MarginSummary(
      margin,
      marginDetails,
      breakdown);
  }

  private MarginSummary(
      double margin,
      List<NamedValue> marginDetails,
      MarginBreakdown breakdown) {
    JodaBeanUtils.notNull(marginDetails, "marginDetails");
    JodaBeanUtils.notNull(breakdown, "breakdown");
    this.margin = margin;
    this.marginDetails = Collections.unmodifiableList(new ArrayList<>(marginDetails));
    this.breakdown = breakdown;
  }

  @Override
  public MetaBean metaBean() {
    return MarginSummary.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the total margin, expressed in the reporting currency.
   * @return the value of the property
   */
  public double getMargin() {
    return margin;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the CCP-specific breakdown of the initial margin.
   * @return the value of the property, not null
   */
  public List<NamedValue> getMarginDetails() {
    return marginDetails;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the standardized breakdown of the initial margin.
   * <p>
   * The contents of {@link #getMarginDetails()} are CCP-specific.
   * This breakdown summarizes the values under three standardized headings.
   * @return the value of the property, not null
   */
  public MarginBreakdown getBreakdown() {
    return breakdown;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      MarginSummary other = (MarginSummary) obj;
      return JodaBeanUtils.equal(margin, other.margin) &&
          JodaBeanUtils.equal(marginDetails, other.marginDetails) &&
          JodaBeanUtils.equal(breakdown, other.breakdown);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(margin);
    hash = hash * 31 + JodaBeanUtils.hashCode(marginDetails);
    hash = hash * 31 + JodaBeanUtils.hashCode(breakdown);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(128);
    buf.append("MarginSummary{");
    buf.append("margin").append('=').append(JodaBeanUtils.toString(margin)).append(',').append(' ');
    buf.append("marginDetails").append('=').append(JodaBeanUtils.toString(marginDetails)).append(',').append(' ');
    buf.append("breakdown").append('=').append(JodaBeanUtils.toString(breakdown));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code MarginSummary}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code margin} property.
     */
    private final MetaProperty<Double> margin = DirectMetaProperty.ofImmutable(
        this, "margin", MarginSummary.class, Double.TYPE);
    /**
     * The meta-property for the {@code marginDetails} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<NamedValue>> marginDetails = DirectMetaProperty.ofImmutable(
        this, "marginDetails", MarginSummary.class, (Class) List.class);
    /**
     * The meta-property for the {@code breakdown} property.
     */
    private final MetaProperty<MarginBreakdown> breakdown = DirectMetaProperty.ofImmutable(
        this, "breakdown", MarginSummary.class, MarginBreakdown.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "margin",
        "marginDetails",
        "breakdown");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case -1081309778:  // margin
          return margin;
        case 1113711796:  // marginDetails
          return marginDetails;
        case -1897470431:  // breakdown
          return breakdown;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends MarginSummary> builder() {
      return new MarginSummary.Builder();
    }

    @Override
    public Class<? extends MarginSummary> beanType() {
      return MarginSummary.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -1081309778:  // margin
          return ((MarginSummary) bean).getMargin();
        case 1113711796:  // marginDetails
          return ((MarginSummary) bean).getMarginDetails();
        case -1897470431:  // breakdown
          return ((MarginSummary) bean).getBreakdown();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code MarginSummary}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<MarginSummary> {

    private double margin;
    private List<NamedValue> marginDetails = Collections.emptyList();
    private MarginBreakdown breakdown;

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case -1081309778:  // margin
          return margin;
        case 1113711796:  // marginDetails
          return marginDetails;
        case -1897470431:  // breakdown
          return breakdown;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case -1081309778:  // margin
          this.margin = (Double) newValue;
          break;
        case 1113711796:  // marginDetails
          this.marginDetails = (List<NamedValue>) newValue;
          break;
        case -1897470431:  // breakdown
          this.breakdown = (MarginBreakdown) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public MarginSummary build() {
      return new MarginSummary(
          margin,
          marginDetails,
          breakdown);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(128);
      buf.append("MarginSummary.Builder{");
      buf.append("margin").append('=').append(JodaBeanUtils.toString(margin)).append(',').append(' ');
      buf.append("marginDetails").append('=').append(JodaBeanUtils.toString(marginDetails)).append(',').append(' ');
      buf.append("breakdown").append('=').append(JodaBeanUtils.toString(breakdown));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private")
public final class PortfolioDataFile implements ImmutableBean {

  /**
   * The portfolio name.
   */
  @PropertyDefinition(validate = "notNull")
  private final String name;
  /**
   * The portfolio data.
   */
  @PropertyDefinition(validate = "notNull")
  private final String data;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance from the String representation of the data.
   * <p>
   * The data is compressed using GZIP, and sent to the server using Base-64.
   *
   * @param name the name, not empty
   * @param data the data, not empty
   * @return the instance
   * @throws UncheckedIOException if an IO error occurs
   */
  public static PortfolioDataFile of(String name, String data) {
    String base64Data = gzipBase64(data);
    return new PortfolioDataFile(name + ".gz.base64", base64Data);
  }

  /**
   * Obtains an instance from a file.
   * <p>
   * The file is compressed using GZIP, and sent to the server using Base-64.
   *
   * @param path the file
   * @return the instance
   * @throws UncheckedIOException if an IO error occurs
   */
  public static PortfolioDataFile of(Path path) {
    String filename = path.toAbsolutePath().toString();
    if (Files.notExists(path)) {
      throw new IllegalArgumentException("Could not find portfolio file: " + filename);
    }
    String base64Data = gzipBase64(path);
    return new PortfolioDataFile(filename + ".gz.base64", base64Data);
  }

  /**
   * Obtains an instance from a bean.
   * <p>
   * The bean should be an instance of a Strata {@code CalculationTarget}, such as a trade or position.
   * If a {@link PortfolioDataFile} is passed in, it is returned unaltered.
   *
   * @param bean the bean
   * @return the instance
   */
  public static PortfolioDataFile of(Bean bean) {
    if (bean instanceof PortfolioDataFile) {
      return (PortfolioDataFile) bean;
    } else {
      String xml = JodaBeanSer.COMPACT.xmlWriter().write(bean);
      return PortfolioDataFile.of(bean.getClass().getSimpleName() + ".xml", xml);
    }
  }

  /**
   * Obtains an instance by combining a list of files.
   * <p>
   * The files are combined using ZIP, and sent to the server using Base-64.
   *
   * @param paths the files, at least one
   * @return the instance
   * @throws IllegalArgumentException if no files were passed in
   * @throws UncheckedIOException if an IO error occurs
   */
  public static PortfolioDataFile ofCombined(List<Path> paths) {
    List<Path> missingFiles = paths.stream().filter(Files::notExists).collect(toList());
    if (!missingFiles.isEmpty()) {
      String missingFilesAsString = missingFiles.stream().map(Path::toString).collect(joining(","));
      throw new IllegalArgumentException("Could not find one or more of the input files in the list." + missingFilesAsString);
    }
    String base64Data = zipBase64(paths);
    return new PortfolioDataFile("JavaSDK.zip.base64", base64Data);
  }

  /**
   * Convert input to bytes using UTF-8, gzip it, then base-64 it.
   *
   * @param data the input data, as a String
   * @return the compressed output, as a String
   */
  private static String gzipBase64(String data) {
    try {
      try (ByteArrayOutputStream baos = new ByteArrayOutputStream(data.length() / 4 + 1)) {
        try (OutputStream baseos = Base64.getEncoder().wrap(baos)) {
          try (GZIPOutputStream zos = new GZIPOutputStream(baseos)) {
            try (OutputStreamWriter writer = new OutputStreamWriter(zos, StandardCharsets.UTF_8)) {
              writer.write(data);
            }
          }
        }
        return baos.toString("ISO-8859-1");  // base-64 bytes are ASCII, so this is optimal
      }
    } catch (IOException ex) {
      throw new UncheckedIOException("Failed to gzip base-64 content", ex);
    }
  }

  /**
   * Gzips the input then base-64 it.
   *
   * @param path the input data file, as an instance of {@link Path}
   * @return the compressed output, as a String
   */
  private static String gzipBase64(Path path) {
    try {
      long size = Files.size(path) / 4 + 1;
      int initialSize = size > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) size;
      try (ByteArrayOutputStream baos = new ByteArrayOutputStream(initialSize)) {
        try (OutputStream baseos = Base64.getEncoder().wrap(baos)) {
          try (GZIPOutputStream zos = new GZIPOutputStream(baseos)) {
            Files.copy(path, zos);
          }
        }
        return baos.toString("ISO-8859-1");  // base-64 bytes are ASCII, so this is optimal
      }
    } catch (IOException ex) {
      throw new UncheckedIOException("Failed to gzip base-64 content", ex);
    }
  }

  /**
   * Combines multiple files into a ZIP archive, then base-64 the ZIP archive.
   *
   * @param paths a list of one or more input files, that are to be compressed together
   * @return the compressed output, as a String
   */
  private static String zipBase64(List<Path> paths) {
    if (paths.isEmpty()) {
      throw new IllegalArgumentException("PortfolioDataFile requires at least one file");
    }
    try {
      try (ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 8)) {
        try (OutputStream baseos = Base64.getEncoder().wrap(baos)) {
          try (ZipOutputStream zos = new ZipOutputStream(baseos)) {
            for (Path path : paths) {
              ZipEntry entry = new ZipEntry(path.getFileName().toString());
              zos.putNextEntry(entry);
              Files.copy(path, zos);
              zos.closeEntry();
            }
          }
        }
        return baos.toString("ISO-8859-1");  // base-64 bytes are ASCII, so this is optimal
      }
    } catch (IOException ex) {
      throw new UncheckedIOException("Failed to zip base-64 content", ex);
    }
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code PortfolioDataFile}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return PortfolioDataFile.Meta.INSTANCE;
  }

  static {
    MetaBean.register(PortfolioDataFile.Meta.INSTANCE);
  }

  private PortfolioDataFile(
      String name,
      String data) {
    JodaBeanUtils.notNull(name, "name");
    JodaBeanUtils.notNull(data, "data");
    this.name = name;
    this.data = data;
  }

  @Override
  public MetaBean metaBean() {
    return PortfolioDataFile.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the portfolio name.
   * @return the value of the property, not null
   */
  public String getName() {
    return name;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the portfolio data.
   * @return the value of the property, not null
   */
  public String getData() {
    return data;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      PortfolioDataFile other = (PortfolioDataFile) obj;
      return JodaBeanUtils.equal(name, other.name) &&
          JodaBeanUtils.equal(data, other.data);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(name);
    hash = hash * 31 + JodaBeanUtils.hashCode(data);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(96);
    buf.append("PortfolioDataFile{");
    buf.append("name").append('=').append(JodaBeanUtils.toString(name)).append(',').append(' ');
    buf.append("data").append('=').append(JodaBeanUtils.toString(data));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code PortfolioDataFile}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code name} property.
     */
    private final MetaProperty<String> name = DirectMetaProperty.ofImmutable(
        this, "name", PortfolioDataFile.class, String.class);
    /**
     * The meta-property for the {@code data} property.
     */
    private final MetaProperty<String> data = DirectMetaProperty.ofImmutable(
        this, "data", PortfolioDataFile.class, String.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "name",
        "data");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 3373707:  // name
          return name;
        case 3076010:  // data
          return data;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends PortfolioDataFile> builder() {
      return new PortfolioDataFile.Builder();
    }

    @Override
    public Class<? extends PortfolioDataFile> beanType() {
      return PortfolioDataFile.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 3373707:  // name
          return ((PortfolioDataFile) bean).getName();
        case 3076010:  // data
          return ((PortfolioDataFile) bean).getData();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code PortfolioDataFile}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<PortfolioDataFile> {

    private String name;
    private String data;

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 3373707:  // name
          return name;
        case 3076010:  // data
          return data;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 3373707:  // name
          this.name = (String) newValue;
          break;
        case 3076010:  // data
          this.data = (String) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public PortfolioDataFile build() {
      return new PortfolioDataFile(
          name,
          data);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(96);
      buf.append("PortfolioDataFile.Builder{");
      buf.append("name").append('=').append(JodaBeanUtils.toString(name)).append(',').append(' ');
      buf.append("data").append('=').append(JodaBeanUtils.toString(data));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class TradeCurveSensitivity implements ImmutableBean {

  /**
   * The name of the curve that the sensitivities relate to.
   */
  @PropertyDefinition(validate = "notNull")
  private final String curveName;
  /**
   * The currency of the sensitivities, as an ISO 4217 three letter currency code.
   * This is the currency of the sensitivities of the curve.
   */
  @PropertyDefinition(validate = "notNull")
  private final String currency;
  /**
   * The total sensitivity, calculated as the sum of all the tenor values.
   * This is expressed in the specified currency.
   */
  @PropertyDefinition
  private final double sensitivity;
  /**
   * The per-tenor sensitivity.
   * Values are expressed in the specified currency.
   */
  @PropertyDefinition(validate = "notNull")
  private final Map<Period, Double> tenorSensitivity;

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code TradeCurveSensitivity}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return TradeCurveSensitivity.Meta.INSTANCE;
  }

  static {
    MetaBean.register(TradeCurveSensitivity.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param curveName  the value of the property, not null
   * @param currency  the value of the property, not null
   * @param sensitivity  the value of the property
   * @param tenorSensitivity  the value of the property, not null
   * @return the instance
   */
  public static TradeCurveSensitivity of(
      String curveName,
      String currency,
      double sensitivity,
      Map<Period, Double> tenorSensitivity) {
    return new TradeCurveSensitivity(
      curveName,
      currency,
      sensitivity,
      tenorSensitivity);
  }

  private TradeCurveSensitivity(
      String curveName,
      String currency,
      double sensitivity,
      Map<Period, Double> tenorSensitivity) {
    JodaBeanUtils.notNull(curveName, "curveName");
    JodaBeanUtils.notNull(currency, "currency");
    JodaBeanUtils.notNull(tenorSensitivity, "tenorSensitivity");
    this.curveName = curveName;
    this.currency = currency;
    this.sensitivity = sensitivity;
    this.tenorSensitivity = Collections.unmodifiableMap(new HashMap<>(tenorSensitivity));
  }

  @Override
  public MetaBean metaBean() {
    return TradeCurveSensitivity.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the name of the curve that the sensitivities relate to.
   * @return the value of the property, not null
   */
  public String getCurveName() {
    return curveName;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the currency of the sensitivities, as an ISO 4217 three letter currency code.
   * This is the currency of the sensitivities of the curve.
   * @return the value of the property, not null
   */
  public String getCurrency() {
    return currency;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the total sensitivity, calculated as the sum of all the tenor values.
   * This is expressed in the specified currency.
   * @return the value of the property
   */
  public double getSensitivity() {
    return sensitivity;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the per-tenor sensitivity.
   * Values are expressed in the specified currency.
   * @return the value of the property, not null
   */
  public Map<Period, Double> getTenorSensitivity() {
    return tenorSensitivity;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      TradeCurveSensitivity other = (TradeCurveSensitivity) obj;
      return JodaBeanUtils.equal(curveName, other.curveName) &&
          JodaBeanUtils.equal(currency, other.currency) &&
          JodaBeanUtils.equal(sensitivity, other.sensitivity) &&
          JodaBeanUtils.equal(tenorSensitivity, other.tenorSensitivity);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(curveName);
    hash = hash * 31 + JodaBeanUtils.hashCode(currency);
    hash = hash * 31 + JodaBeanUtils.hashCode(sensitivity);
    hash = hash * 31 + JodaBeanUtils.hashCode(tenorSensitivity);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(160);
    buf.append("TradeCurveSensitivity{");
    buf.append("curveName").append('=').append(JodaBeanUtils.toString(curveName)).append(',').append(' ');
    buf.append("currency").append('=').append(JodaBeanUtils.toString(currency)).append(',').append(' ');
    buf.append("sensitivity").append('=').append(JodaBeanUtils.toString(sensitivity)).append(',').append(' ');
    buf.append("tenorSensitivity").append('=').append(JodaBeanUtils.toString(tenorSensitivity));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code TradeCurveSensitivity}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code curveName} property.
     */
    private final MetaProperty<String> curveName = DirectMetaProperty.ofImmutable(
        this, "curveName", TradeCurveSensitivity.class, String.class);
    /**
     * The meta-property for the {@code currency} property.
     */
    private final MetaProperty<String> currency = DirectMetaProperty.ofImmutable(
        this, "currency", TradeCurveSensitivity.class, String.class);
    /**
     * The meta-property for the {@code sensitivity} property.
     */
    private final MetaProperty<Double> sensitivity = DirectMetaProperty.ofImmutable(
        this, "sensitivity", TradeCurveSensitivity.class, Double.TYPE);
    /**
     * The meta-property for the {@code tenorSensitivity} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<Map<Period, Double>> tenorSensitivity = DirectMetaProperty.ofImmutable(
        this, "tenorSensitivity", TradeCurveSensitivity.class, (Class) Map.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "curveName",
        "currency",
        "sensitivity",
        "tenorSensitivity");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 771153946:  // curveName
          return curveName;
        case 575402001:  // currency
          return currency;
        case 564403871:  // sensitivity
          return sensitivity;
        case 334451647:  // tenorSensitivity
          return tenorSensitivity;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends TradeCurveSensitivity> builder() {
      return new TradeCurveSensitivity.Builder();
    }

    @Override
    public Class<? extends TradeCurveSensitivity> beanType() {
      return TradeCurveSensitivity.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 771153946:  // curveName
          return ((TradeCurveSensitivity) bean).getCurveName();
        case 575402001:  // currency
          return ((TradeCurveSensitivity) bean).getCurrency();
        case 564403871:  // sensitivity
          return ((TradeCurveSensitivity) bean).getSensitivity();
        case 334451647:  // tenorSensitivity
          return ((TradeCurveSensitivity) bean).getTenorSensitivity();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code TradeCurveSensitivity}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<TradeCurveSensitivity> {

    private String curveName;
    private String currency;
    private double sensitivity;
    private Map<Period, Double> tenorSensitivity = Collections.emptyMap();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 771153946:  // curveName
          return curveName;
        case 575402001:  // currency
          return currency;
        case 564403871:  // sensitivity
          return sensitivity;
        case 334451647:  // tenorSensitivity
          return tenorSensitivity;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 771153946:  // curveName
          this.curveName = (String) newValue;
          break;
        case 575402001:  // currency
          this.currency = (String) newValue;
          break;
        case 564403871:  // sensitivity
          this.sensitivity = (Double) newValue;
          break;
        case 334451647:  // tenorSensitivity
          this.tenorSensitivity = (Map<Period, Double>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public TradeCurveSensitivity build() {
      return new TradeCurveSensitivity(
          curveName,
          currency,
          sensitivity,
          tenorSensitivity);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(160);
      buf.append("TradeCurveSensitivity.Builder{");
      buf.append("curveName").append('=').append(JodaBeanUtils.toString(curveName)).append(',').append(' ');
      buf.append("currency").append('=').append(JodaBeanUtils.toString(currency)).append(',').append(' ');
      buf.append("sensitivity").append('=').append(JodaBeanUtils.toString(sensitivity)).append(',').append(' ');
      buf.append("tenorSensitivity").append('=').append(JodaBeanUtils.toString(tenorSensitivity));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class TradeSensitivity implements ImmutableBean {

  /**
   * The total sensitivity, calculated as the sum of all the curves, expressed in the reporting currency.
   */
  @PropertyDefinition
  private final double sensitivity;
  /**
   * The list of curve sensitivities.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<TradeCurveSensitivity> curveSensitivity;

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code TradeSensitivity}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return TradeSensitivity.Meta.INSTANCE;
  }

  static {
    MetaBean.register(TradeSensitivity.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param sensitivity  the value of the property
   * @param curveSensitivity  the value of the property, not null
   * @return the instance
   */
  public static TradeSensitivity of(
      double sensitivity,
      List<TradeCurveSensitivity> curveSensitivity) {
    return new TradeSensitivity(
      sensitivity,
      curveSensitivity);
  }

  private TradeSensitivity(
      double sensitivity,
      List<TradeCurveSensitivity> curveSensitivity) {
    JodaBeanUtils.notNull(curveSensitivity, "curveSensitivity");
    this.sensitivity = sensitivity;
    this.curveSensitivity = Collections.unmodifiableList(new ArrayList<>(curveSensitivity));
  }

  @Override
  public MetaBean metaBean() {
    return TradeSensitivity.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the total sensitivity, calculated as the sum of all the curves, expressed in the reporting currency.
   * @return the value of the property
   */
  public double getSensitivity() {
    return sensitivity;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the list of curve sensitivities.
   * @return the value of the property, not null
   */
  public List<TradeCurveSensitivity> getCurveSensitivity() {
    return curveSensitivity;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      TradeSensitivity other = (TradeSensitivity) obj;
      return JodaBeanUtils.equal(sensitivity, other.sensitivity) &&
          JodaBeanUtils.equal(curveSensitivity, other.curveSensitivity);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(sensitivity);
    hash = hash * 31 + JodaBeanUtils.hashCode(curveSensitivity);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(96);
    buf.append("TradeSensitivity{");
    buf.append("sensitivity").append('=').append(JodaBeanUtils.toString(sensitivity)).append(',').append(' ');
    buf.append("curveSensitivity").append('=').append(JodaBeanUtils.toString(curveSensitivity));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code TradeSensitivity}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code sensitivity} property.
     */
    private final MetaProperty<Double> sensitivity = DirectMetaProperty.ofImmutable(
        this, "sensitivity", TradeSensitivity.class, Double.TYPE);
    /**
     * The meta-property for the {@code curveSensitivity} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<TradeCurveSensitivity>> curveSensitivity = DirectMetaProperty.ofImmutable(
        this, "curveSensitivity", TradeSensitivity.class, (Class) List.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "sensitivity",
        "curveSensitivity");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 564403871:  // sensitivity
          return sensitivity;
        case 1610426928:  // curveSensitivity
          return curveSensitivity;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends TradeSensitivity> builder() {
      return new TradeSensitivity.Builder();
    }

    @Override
    public Class<? extends TradeSensitivity> beanType() {
      return TradeSensitivity.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 564403871:  // sensitivity
          return ((TradeSensitivity) bean).getSensitivity();
        case 1610426928:  // curveSensitivity
          return ((TradeSensitivity) bean).getCurveSensitivity();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code TradeSensitivity}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<TradeSensitivity> {

    private double sensitivity;
    private List<TradeCurveSensitivity> curveSensitivity = Collections.emptyList();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 564403871:  // sensitivity
          return sensitivity;
        case 1610426928:  // curveSensitivity
          return curveSensitivity;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 564403871:  // sensitivity
          this.sensitivity = (Double) newValue;
          break;
        case 1610426928:  // curveSensitivity
          this.curveSensitivity = (List<TradeCurveSensitivity>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public TradeSensitivity build() {
      return new TradeSensitivity(
          sensitivity,
          curveSensitivity);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(96);
      buf.append("TradeSensitivity.Builder{");
      buf.append("sensitivity").append('=').append(JodaBeanUtils.toString(sensitivity)).append(',').append(' ');
      buf.append("curveSensitivity").append('=').append(JodaBeanUtils.toString(curveSensitivity));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class TradeValuation implements ImmutableBean {

  /**
   * The trade identifier, empty if not known.
   */
  @PropertyDefinition(validate = "notNull")
  private final String tradeId;
  /**
   * The value of the trade, in the trade currency.
   */
  @PropertyDefinition(get = "optional")
  private final TradeValue value;
  /**
   * The delta of the trade.
   */
  @PropertyDefinition(get = "optional")
  private final TradeSensitivity delta;
  /**
   * The gamma of the trade.
   */
  @PropertyDefinition(get = "optional")
  private final TradeSensitivity gamma;

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code TradeValuation}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return TradeValuation.Meta.INSTANCE;
  }

  static {
    MetaBean.register(TradeValuation.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param tradeId  the value of the property, not null
   * @param value  the value of the property
   * @param delta  the value of the property
   * @param gamma  the value of the property
   * @return the instance
   */
  public static TradeValuation of(
      String tradeId,
      TradeValue value,
      TradeSensitivity delta,
      TradeSensitivity gamma) {
    return new TradeValuation(
      tradeId,
      value,
      delta,
      gamma);
  }

  private TradeValuation(
      String tradeId,
      TradeValue value,
      TradeSensitivity delta,
      TradeSensitivity gamma) {
    JodaBeanUtils.notNull(tradeId, "tradeId");
    this.tradeId = tradeId;
    this.value = value;
    this.delta = delta;
    this.gamma = gamma;
  }

  @Override
  public MetaBean metaBean() {
    return TradeValuation.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the trade identifier, empty if not known.
   * @return the value of the property, not null
   */
  public String getTradeId() {
    return tradeId;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the value of the trade, in the trade currency.
   * @return the optional value of the property, not null
   */
  public Optional<TradeValue> getValue() {
    return Optional.ofNullable(value);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the delta of the trade.
   * @return the optional value of the property, not null
   */
  public Optional<TradeSensitivity> getDelta() {
    return Optional.ofNullable(delta);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the gamma of the trade.
   * @return the optional value of the property, not null
   */
  public Optional<TradeSensitivity> getGamma() {
    return Optional.ofNullable(gamma);
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      TradeValuation other = (TradeValuation) obj;
      return JodaBeanUtils.equal(tradeId, other.tradeId) &&
          JodaBeanUtils.equal(value, other.value) &&
          JodaBeanUtils.equal(delta, other.delta) &&
          JodaBeanUtils.equal(gamma, other.gamma);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(tradeId);
    hash = hash * 31 + JodaBeanUtils.hashCode(value);
    hash = hash * 31 + JodaBeanUtils.hashCode(delta);
    hash = hash * 31 + JodaBeanUtils.hashCode(gamma);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(160);
    buf.append("TradeValuation{");
    buf.append("tradeId").append('=').append(JodaBeanUtils.toString(tradeId)).append(',').append(' ');
    buf.append("value").append('=').append(JodaBeanUtils.toString(value)).append(',').append(' ');
    buf.append("delta").append('=').append(JodaBeanUtils.toString(delta)).append(',').append(' ');
    buf.append("gamma").append('=').append(JodaBeanUtils.toString(gamma));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code TradeValuation}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code tradeId} property.
     */
    private final MetaProperty<String> tradeId = DirectMetaProperty.ofImmutable(
        this, "tradeId", TradeValuation.class, String.class);
    /**
     * The meta-property for the {@code value} property.
     */
    private final MetaProperty<TradeValue> value = DirectMetaProperty.ofImmutable(
        this, "value", TradeValuation.class, TradeValue.class);
    /**
     * The meta-property for the {@code delta} property.
     */
    private final MetaProperty<TradeSensitivity> delta = DirectMetaProperty.ofImmutable(
        this, "delta", TradeValuation.class, TradeSensitivity.class);
    /**
     * The meta-property for the {@code gamma} property.
     */
    private final MetaProperty<TradeSensitivity> gamma = DirectMetaProperty.ofImmutable(
        this, "gamma", TradeValuation.class, TradeSensitivity.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "tradeId",
        "value",
        "delta",
        "gamma");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case -1067372129:  // tradeId
          return tradeId;
        case 111972721:  // value
          return value;
        case 95468472:  // delta
          return delta;
        case 98120615:  // gamma
          return gamma;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends TradeValuation> builder() {
      return new TradeValuation.Builder();
    }

    @Override
    public Class<? extends TradeValuation> beanType() {
      return TradeValuation.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -1067372129:  // tradeId
          return ((TradeValuation) bean).getTradeId();
        case 111972721:  // value
          return ((TradeValuation) bean).value;
        case 95468472:  // delta
          return ((TradeValuation) bean).delta;
        case 98120615:  // gamma
          return ((TradeValuation) bean).gamma;
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code TradeValuation}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<TradeValuation> {

    private String tradeId;
    private TradeValue value;
    private TradeSensitivity delta;
    private TradeSensitivity gamma;

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case -1067372129:  // tradeId
          return tradeId;
        case 111972721:  // value
          return value;
        case 95468472:  // delta
          return delta;
        case 98120615:  // gamma
          return gamma;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case -1067372129:  // tradeId
          this.tradeId = (String) newValue;
          break;
        case 111972721:  // value
          this.value = (TradeValue) newValue;
          break;
        case 95468472:  // delta
          this.delta = (TradeSensitivity) newValue;
          break;
        case 98120615:  // gamma
          this.gamma = (TradeSensitivity) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public TradeValuation build() {
      return new TradeValuation(
          tradeId,
          value,
          delta,
          gamma);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(160);
      buf.append("TradeValuation.Builder{");
      buf.append("tradeId").append('=').append(JodaBeanUtils.toString(tradeId)).append(',').append(' ');
      buf.append("value").append('=').append(JodaBeanUtils.toString(value)).append(',').append(' ');
      buf.append("delta").append('=').append(JodaBeanUtils.toString(delta)).append(',').append(' ');
      buf.append("gamma").append('=').append(JodaBeanUtils.toString(gamma));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class TradeValuations implements ImmutableBean {

  /**
   * The total present value for all trades.
   * <p>
   * The value is expressed in the reporting currency.
   * Note that this is the sum of all the trade-level present values.
   */
  @PropertyDefinition
  private final double totalPresentValue;
  /**
   * The total delta for all trades.
   * <p>
   * The value is expressed in the reporting currency.
   * Note that this is the sum of all the trade-level deltas.
   */
  @PropertyDefinition(get = "optional")
  private final Double totalDelta;
  /**
   * The per-curve delta.
   * <p>
   * The values are expressed in the currency of the curve.
   * Note that these are the sums of all the trade-level delta curves.
   * <p>
   * Populated only when margin calculation type {@link MarginCalcType#DELTA DELTA} has been requested.
   */
  @PropertyDefinition(get = "optional")
  private final List<TradeCurveSensitivity> bucketedDelta;
  /**
   * The total gamma for all trades.
   * <p>
   * The value is expressed in the reporting currency.
   * Note that this is the sum of all the trade-level gamma.
   */
  @PropertyDefinition(get = "optional")
  private final Double totalGamma;
  /**
   * The per-curve gamma.
   * <p>
   * The values are expressed in the currency of the curve.
   * Note that these are the sums of all the trade-level gamma curves.
   * <p>
   * Populated only when margin calculation type {@link MarginCalcType#GAMMA GAMMA} has been requested.
   */
  @PropertyDefinition(get = "optional")
  private final List<TradeCurveSensitivity> bucketedGamma;
  /**
   * The per-trade valuation.
   * <p>
   * An entry will be added for each trade where the valuation was calculated.
   */
  @PropertyDefinition(validate = "notNull")
  private final List<TradeValuation> trades;

  //-------------------------------------------------------------------------
  /**
   * Obtains an instance.
   * 
   * @param totalPresentValue  the value of the property
   * @param totalDelta  the value of the property
   * @param totalGamma  the value of the property
   * @param trades  the value of the property, not null
   * @return the instance
   * @deprecated Use variation with 6 arguments
   */
  @Deprecated
  public static TradeValuations of(
      double totalPresentValue,
      Double totalDelta,
      Double totalGamma,
      List<TradeValuation> trades) {

    return new TradeValuations(totalPresentValue, totalDelta, null, totalGamma, null, trades);
  }

  @ImmutablePreBuild
  private static void preBuild(Builder builder) {
    if (builder.totalDelta == null) {
      builder.bucketedDelta = null;
    }
    if (builder.totalGamma == null) {
      builder.bucketedGamma = null;
    }
  }

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code TradeValuations}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return TradeValuations.Meta.INSTANCE;
  }

  static {
    MetaBean.register(TradeValuations.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param totalPresentValue  the value of the property
   * @param totalDelta  the value of the property
   * @param bucketedDelta  the value of the property
   * @param totalGamma  the value of the property
   * @param bucketedGamma  the value of the property
   * @param trades  the value of the property, not null
   * @return the instance
   */
  public static TradeValuations of(
      double totalPresentValue,
      Double totalDelta,
      List<TradeCurveSensitivity> bucketedDelta,
      Double totalGamma,
      List<TradeCurveSensitivity> bucketedGamma,
      List<TradeValuation> trades) {
    return new TradeValuations(
      totalPresentValue,
      totalDelta,
      bucketedDelta,
      totalGamma,
      bucketedGamma,
      trades);
  }

  private TradeValuations(
      double totalPresentValue,
      Double totalDelta,
      List<TradeCurveSensitivity> bucketedDelta,
      Double totalGamma,
      List<TradeCurveSensitivity> bucketedGamma,
      List<TradeValuation> trades) {
    JodaBeanUtils.notNull(trades, "trades");
    this.totalPresentValue = totalPresentValue;
    this.totalDelta = totalDelta;
    this.bucketedDelta = (bucketedDelta != null ? Collections.unmodifiableList(new ArrayList<>(bucketedDelta)) : null);
    this.totalGamma = totalGamma;
    this.bucketedGamma = (bucketedGamma != null ? Collections.unmodifiableList(new ArrayList<>(bucketedGamma)) : null);
    this.trades = Collections.unmodifiableList(new ArrayList<>(trades));
  }

  @Override
  public MetaBean metaBean() {
    return TradeValuations.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the total present value for all trades.
   * <p>
   * The value is expressed in the reporting currency.
   * Note that this is the sum of all the trade-level present values.
   * @return the value of the property
   */
  public double getTotalPresentValue() {
    return totalPresentValue;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the total delta for all trades.
   * <p>
   * The value is expressed in the reporting currency.
   * Note that this is the sum of all the trade-level deltas.
   * @return the optional value of the property, not null
   */
  public OptionalDouble getTotalDelta() {
    return totalDelta != null ? OptionalDouble.of(totalDelta) : OptionalDouble.empty();
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the per-curve delta.
   * <p>
   * The values are expressed in the currency of the curve.
   * Note that these are the sums of all the trade-level delta curves.
   * <p>
   * Populated only when margin calculation type {@link MarginCalcType#DELTA DELTA} has been requested.
   * @return the optional value of the property, not null
   */
  public Optional<List<TradeCurveSensitivity>> getBucketedDelta() {
    return Optional.ofNullable(bucketedDelta);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the total gamma for all trades.
   * <p>
   * The value is expressed in the reporting currency.
   * Note that this is the sum of all the trade-level gamma.
   * @return the optional value of the property, not null
   */
  public OptionalDouble getTotalGamma() {
    return totalGamma != null ? OptionalDouble.of(totalGamma) : OptionalDouble.empty();
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the per-curve gamma.
   * <p>
   * The values are expressed in the currency of the curve.
   * Note that these are the sums of all the trade-level gamma curves.
   * <p>
   * Populated only when margin calculation type {@link MarginCalcType#GAMMA GAMMA} has been requested.
   * @return the optional value of the property, not null
   */
  public Optional<List<TradeCurveSensitivity>> getBucketedGamma() {
    return Optional.ofNullable(bucketedGamma);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the per-trade valuation.
   * <p>
   * An entry will be added for each trade where the valuation was calculated.
   * @return the value of the property, not null
   */
  public List<TradeValuation> getTrades() {
    return trades;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      TradeValuations other = (TradeValuations) obj;
      return JodaBeanUtils.equal(totalPresentValue, other.totalPresentValue) &&
          JodaBeanUtils.equal(totalDelta, other.totalDelta) &&
          JodaBeanUtils.equal(bucketedDelta, other.bucketedDelta) &&
          JodaBeanUtils.equal(totalGamma, other.totalGamma) &&
          JodaBeanUtils.equal(bucketedGamma, other.bucketedGamma) &&
          JodaBeanUtils.equal(trades, other.trades);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(totalPresentValue);
    hash = hash * 31 + JodaBeanUtils.hashCode(totalDelta);
    hash = hash * 31 + JodaBeanUtils.hashCode(bucketedDelta);
    hash = hash * 31 + JodaBeanUtils.hashCode(totalGamma);
    hash = hash * 31 + JodaBeanUtils.hashCode(bucketedGamma);
    hash = hash * 31 + JodaBeanUtils.hashCode(trades);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(224);
    buf.append("TradeValuations{");
    buf.append("totalPresentValue").append('=').append(JodaBeanUtils.toString(totalPresentValue)).append(',').append(' ');
    buf.append("totalDelta").append('=').append(JodaBeanUtils.toString(totalDelta)).append(',').append(' ');
    buf.append("bucketedDelta").append('=').append(JodaBeanUtils.toString(bucketedDelta)).append(',').append(' ');
    buf.append("totalGamma").append('=').append(JodaBeanUtils.toString(totalGamma)).append(',').append(' ');
    buf.append("bucketedGamma").append('=').append(JodaBeanUtils.toString(bucketedGamma)).append(',').append(' ');
    buf.append("trades").append('=').append(JodaBeanUtils.toString(trades));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code TradeValuations}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code totalPresentValue} property.
     */
    private final MetaProperty<Double> totalPresentValue = DirectMetaProperty.ofImmutable(
        this, "totalPresentValue", TradeValuations.class, Double.TYPE);
    /**
     * The meta-property for the {@code totalDelta} property.
     */
    private final MetaProperty<Double> totalDelta = DirectMetaProperty.ofImmutable(
        this, "totalDelta", TradeValuations.class, Double.class);
    /**
     * The meta-property for the {@code bucketedDelta} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<TradeCurveSensitivity>> bucketedDelta = DirectMetaProperty.ofImmutable(
        this, "bucketedDelta", TradeValuations.class, (Class) List.class);
    /**
     * The meta-property for the {@code totalGamma} property.
     */
    private final MetaProperty<Double> totalGamma = DirectMetaProperty.ofImmutable(
        this, "totalGamma", TradeValuations.class, Double.class);
    /**
     * The meta-property for the {@code bucketedGamma} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<TradeCurveSensitivity>> bucketedGamma = DirectMetaProperty.ofImmutable(
        this, "bucketedGamma", TradeValuations.class, (Class) List.class);
    /**
     * The meta-property for the {@code trades} property.
     */
    @SuppressWarnings({"unchecked", "rawtypes" })
    private final MetaProperty<List<TradeValuation>> trades = DirectMetaProperty.ofImmutable(
        this, "trades", TradeValuations.class, (Class) List.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "totalPresentValue",
        "totalDelta",
        "bucketedDelta",
        "totalGamma",
        "bucketedGamma",
        "trades");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 2040975066:  // totalPresentValue
          return totalPresentValue;
        case -730768684:  // totalDelta
          return totalDelta;
        case -1611897553:  // bucketedDelta
          return bucketedDelta;
        case -728116541:  // totalGamma
          return totalGamma;
        case -1609245410:  // bucketedGamma
          return bucketedGamma;
        case -865715313:  // trades
          return trades;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends TradeValuations> builder() {
      return new TradeValuations.Builder();
    }

    @Override
    public Class<? extends TradeValuations> beanType() {
      return TradeValuations.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 2040975066:  // totalPresentValue
          return ((TradeValuations) bean).getTotalPresentValue();
        case -730768684:  // totalDelta
          return ((TradeValuations) bean).totalDelta;
        case -1611897553:  // bucketedDelta
          return ((TradeValuations) bean).bucketedDelta;
        case -728116541:  // totalGamma
          return ((TradeValuations) bean).totalGamma;
        case -1609245410:  // bucketedGamma
          return ((TradeValuations) bean).bucketedGamma;
        case -865715313:  // trades
          return ((TradeValuations) bean).getTrades();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code TradeValuations}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<TradeValuations> {

    private double totalPresentValue;
    private Double totalDelta;
    private List<TradeCurveSensitivity> bucketedDelta;
    private Double totalGamma;
    private List<TradeCurveSensitivity> bucketedGamma;
    private List<TradeValuation> trades = Collections.emptyList();

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 2040975066:  // totalPresentValue
          return totalPresentValue;
        case -730768684:  // totalDelta
          return totalDelta;
        case -1611897553:  // bucketedDelta
          return bucketedDelta;
        case -728116541:  // totalGamma
          return totalGamma;
        case -1609245410:  // bucketedGamma
          return bucketedGamma;
        case -865715313:  // trades
          return trades;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @SuppressWarnings("unchecked")
    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 2040975066:  // totalPresentValue
          this.totalPresentValue = (Double) newValue;
          break;
        case -730768684:  // totalDelta
          this.totalDelta = (Double) newValue;
          break;
        case -1611897553:  // bucketedDelta
          this.bucketedDelta = (List<TradeCurveSensitivity>) newValue;
          break;
        case -728116541:  // totalGamma
          this.totalGamma = (Double) newValue;
          break;
        case -1609245410:  // bucketedGamma
          this.bucketedGamma = (List<TradeCurveSensitivity>) newValue;
          break;
        case -865715313:  // trades
          this.trades = (List<TradeValuation>) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public TradeValuations build() {
      preBuild(this);
      return new TradeValuations(
          totalPresentValue,
          totalDelta,
          bucketedDelta,
          totalGamma,
          bucketedGamma,
          trades);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(224);
      buf.append("TradeValuations.Builder{");
      buf.append("totalPresentValue").append('=').append(JodaBeanUtils.toString(totalPresentValue)).append(',').append(' ');
      buf.append("totalDelta").append('=').append(JodaBeanUtils.toString(totalDelta)).append(',').append(' ');
      buf.append("bucketedDelta").append('=').append(JodaBeanUtils.toString(bucketedDelta)).append(',').append(' ');
      buf.append("totalGamma").append('=').append(JodaBeanUtils.toString(totalGamma)).append(',').append(' ');
      buf.append("bucketedGamma").append('=').append(JodaBeanUtils.toString(bucketedGamma)).append(',').append(' ');
      buf.append("trades").append('=').append(JodaBeanUtils.toString(trades));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
} @BeanDefinition(builderScope = "private", metaScope = "private", factoryName = "of")
public final class TradeValue implements ImmutableBean {

  /**
   * The present value, expressed in the reporting currency.
   */
  @PropertyDefinition(validate = "notNull")
  private final double presentValue;
  /**
   * The trade currency, as an ISO 4217 three letter currency code.
   */
  @PropertyDefinition(validate = "notNull")
  private final String tradeCurrency;
  /**
   * The present value, expressed in the trade currency.
   */
  @PropertyDefinition(validate = "notNull")
  private final double presentValueTradeCurrency;

  //------------------------- AUTOGENERATED START -------------------------
  /**
   * The meta-bean for {@code TradeValue}.
   * @return the meta-bean, not null
   */
  public static MetaBean meta() {
    return TradeValue.Meta.INSTANCE;
  }

  static {
    MetaBean.register(TradeValue.Meta.INSTANCE);
  }

  /**
   * Obtains an instance.
   * @param presentValue  the value of the property, not null
   * @param tradeCurrency  the value of the property, not null
   * @param presentValueTradeCurrency  the value of the property, not null
   * @return the instance
   */
  public static TradeValue of(
      double presentValue,
      String tradeCurrency,
      double presentValueTradeCurrency) {
    return new TradeValue(
      presentValue,
      tradeCurrency,
      presentValueTradeCurrency);
  }

  private TradeValue(
      double presentValue,
      String tradeCurrency,
      double presentValueTradeCurrency) {
    JodaBeanUtils.notNull(presentValue, "presentValue");
    JodaBeanUtils.notNull(tradeCurrency, "tradeCurrency");
    JodaBeanUtils.notNull(presentValueTradeCurrency, "presentValueTradeCurrency");
    this.presentValue = presentValue;
    this.tradeCurrency = tradeCurrency;
    this.presentValueTradeCurrency = presentValueTradeCurrency;
  }

  @Override
  public MetaBean metaBean() {
    return TradeValue.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the present value, expressed in the reporting currency.
   * @return the value of the property, not null
   */
  public double getPresentValue() {
    return presentValue;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the trade currency, as an ISO 4217 three letter currency code.
   * @return the value of the property, not null
   */
  public String getTradeCurrency() {
    return tradeCurrency;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the present value, expressed in the trade currency.
   * @return the value of the property, not null
   */
  public double getPresentValueTradeCurrency() {
    return presentValueTradeCurrency;
  }

  //-----------------------------------------------------------------------
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      TradeValue other = (TradeValue) obj;
      return JodaBeanUtils.equal(presentValue, other.presentValue) &&
          JodaBeanUtils.equal(tradeCurrency, other.tradeCurrency) &&
          JodaBeanUtils.equal(presentValueTradeCurrency, other.presentValueTradeCurrency);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = getClass().hashCode();
    hash = hash * 31 + JodaBeanUtils.hashCode(presentValue);
    hash = hash * 31 + JodaBeanUtils.hashCode(tradeCurrency);
    hash = hash * 31 + JodaBeanUtils.hashCode(presentValueTradeCurrency);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(128);
    buf.append("TradeValue{");
    buf.append("presentValue").append('=').append(JodaBeanUtils.toString(presentValue)).append(',').append(' ');
    buf.append("tradeCurrency").append('=').append(JodaBeanUtils.toString(tradeCurrency)).append(',').append(' ');
    buf.append("presentValueTradeCurrency").append('=').append(JodaBeanUtils.toString(presentValueTradeCurrency));
    buf.append('}');
    return buf.toString();
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code TradeValue}.
   */
  private static final class Meta extends DirectMetaBean {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code presentValue} property.
     */
    private final MetaProperty<Double> presentValue = DirectMetaProperty.ofImmutable(
        this, "presentValue", TradeValue.class, Double.TYPE);
    /**
     * The meta-property for the {@code tradeCurrency} property.
     */
    private final MetaProperty<String> tradeCurrency = DirectMetaProperty.ofImmutable(
        this, "tradeCurrency", TradeValue.class, String.class);
    /**
     * The meta-property for the {@code presentValueTradeCurrency} property.
     */
    private final MetaProperty<Double> presentValueTradeCurrency = DirectMetaProperty.ofImmutable(
        this, "presentValueTradeCurrency", TradeValue.class, Double.TYPE);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
        this, null,
        "presentValue",
        "tradeCurrency",
        "presentValueTradeCurrency");

    /**
     * Restricted constructor.
     */
    private Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 686253430:  // presentValue
          return presentValue;
        case -50814571:  // tradeCurrency
          return tradeCurrency;
        case -1881703489:  // presentValueTradeCurrency
          return presentValueTradeCurrency;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends TradeValue> builder() {
      return new TradeValue.Builder();
    }

    @Override
    public Class<? extends TradeValue> beanType() {
      return TradeValue.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case 686253430:  // presentValue
          return ((TradeValue) bean).getPresentValue();
        case -50814571:  // tradeCurrency
          return ((TradeValue) bean).getTradeCurrency();
        case -1881703489:  // presentValueTradeCurrency
          return ((TradeValue) bean).getPresentValueTradeCurrency();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      metaProperty(propertyName);
      if (quiet) {
        return;
      }
      throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
    }

  }

  //-----------------------------------------------------------------------
  /**
   * The bean-builder for {@code TradeValue}.
   */
  private static final class Builder extends DirectPrivateBeanBuilder<TradeValue> {

    private double presentValue;
    private String tradeCurrency;
    private double presentValueTradeCurrency;

    /**
     * Restricted constructor.
     */
    private Builder() {
    }

    //-----------------------------------------------------------------------
    @Override
    public Object get(String propertyName) {
      switch (propertyName.hashCode()) {
        case 686253430:  // presentValue
          return presentValue;
        case -50814571:  // tradeCurrency
          return tradeCurrency;
        case -1881703489:  // presentValueTradeCurrency
          return presentValueTradeCurrency;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
    }

    @Override
    public Builder set(String propertyName, Object newValue) {
      switch (propertyName.hashCode()) {
        case 686253430:  // presentValue
          this.presentValue = (Double) newValue;
          break;
        case -50814571:  // tradeCurrency
          this.tradeCurrency = (String) newValue;
          break;
        case -1881703489:  // presentValueTradeCurrency
          this.presentValueTradeCurrency = (Double) newValue;
          break;
        default:
          throw new NoSuchElementException("Unknown property: " + propertyName);
      }
      return this;
    }

    @Override
    public TradeValue build() {
      return new TradeValue(
          presentValue,
          tradeCurrency,
          presentValueTradeCurrency);
    }

    //-----------------------------------------------------------------------
    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder(128);
      buf.append("TradeValue.Builder{");
      buf.append("presentValue").append('=').append(JodaBeanUtils.toString(presentValue)).append(',').append(' ');
      buf.append("tradeCurrency").append('=').append(JodaBeanUtils.toString(tradeCurrency)).append(',').append(' ');
      buf.append("presentValueTradeCurrency").append('=').append(JodaBeanUtils.toString(presentValueTradeCurrency));
      buf.append('}');
      return buf.toString();
    }

  }

  //-------------------------- AUTOGENERATED END --------------------------
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.io.IOException;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.Period;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import com.opengamma.sdk.common.ServiceInvoker;
import com.opengamma.sdk.common.auth.Credentials;
import com.opengamma.sdk.margin.Ccp;
import com.opengamma.sdk.margin.CcpInfo;
import com.opengamma.sdk.margin.CcpsResult;
import com.opengamma.sdk.margin.LchMarginDetail;
import com.opengamma.sdk.margin.LchMarginIndex;
import com.opengamma.sdk.margin.LchMarginScenario;
import com.opengamma.sdk.margin.MarginCalcMode;
import com.opengamma.sdk.margin.MarginCalcRequest;
import com.opengamma.sdk.margin.MarginCalcRequestType;
import com.opengamma.sdk.margin.MarginCalcResult;
import com.opengamma.sdk.margin.MarginCalcResultStatus;
import com.opengamma.sdk.margin.MarginCalcType;
import com.opengamma.sdk.margin.MarginClient;
import com.opengamma.sdk.margin.MarginSummary;
import com.opengamma.sdk.margin.PortfolioDataFile;
import com.opengamma.sdk.margin.TradeCurveSensitivity;
import com.opengamma.sdk.margin.TradeSensitivity;
import com.opengamma.sdk.margin.TradeValuation;
import com.opengamma.sdk.margin.TradeValuations;
import com.opengamma.sdk.margin.TradeValue;
import okhttp3.HttpUrl;
    assertThat(result.getType()).isEqualTo(MarginCalcRequestType.PARSE_INPUTS);
    assertThat(result.getCalculationTypes()).isEqualTo(set(MarginCalcType.PORTFOLIO_SUMMARY));
    assertThat(result.getValuationDate()).isEqualTo(valDate);
    assertThat(result.getReportingCurrency()).isEqualTo("GBP");
    assertThat(result.getCalculationCurrency()).isEqualTo("GBP");
    assertThat(result.getMode()).isEqualTo(MarginCalcMode.SPOT);
    assertThat(result.getPortfolioItems()).hasSize(4);
    assertThat(result.getMargin().isPresent()).isFalse();
    assertThat(result.getMarginDetail().isPresent()).isFalse();
    assertThat(result.getTradeValuations().isPresent()).isFalse();
  }

  @Test
  @Order(10)
  public void test_calculate_margin() throws Exception {
    assumeTrue(valDate != null);
    MarginCalcRequest request = MarginCalcRequest.builder()
        .calculationTypes(MarginCalcType.MARGIN)
        .valuationDate(valDate)
        .reportingCurrency("GBP")
        .portfolioData(PORTFOLIO)
        .build();
    MarginCalcResult result = marginClient.calculate(Ccp.LCH, request);
    assertThat(result.getStatus()).isEqualTo(MarginCalcResultStatus.COMPLETED);
    assertThat(result.getType()).isEqualTo(MarginCalcRequestType.STANDARD);
    assertThat(result.getCalculationTypes()).isEqualTo(set(MarginCalcType.MARGIN));
    assertThat(result.getValuationDate()).isEqualTo(valDate);
    assertThat(result.getReportingCurrency()).isEqualTo("GBP");
    assertThat(result.getCalculationCurrency()).isEqualTo("GBP");
    assertThat(result.getMode()).isEqualTo(MarginCalcMode.SPOT);
    assertThat(result.getPortfolioItems()).hasSize(0);
    assertThat(result.getMargin().isPresent()).isTrue();
    assertThat(result.getMarginDetail().isPresent()).isFalse();
    assertThat(result.getTradeValuations().isPresent()).isFalse();

    MarginSummary margin = result.getMargin().get();
    assertThat(margin.getMargin() != 0).isTrue();
    assertThat(margin.getMarginDetails().size() > 2).isTrue();
    assertThat(margin.getBreakdown().getTotalMargin()).isCloseTo(margin.getMargin(), offset(1e-8));
    assertThat(margin.getBreakdown().getBaseMargin() != 0).isTrue();
    assertThat(margin.getBreakdown().getAddOns() != 0).isTrue();
    assertThat(margin.getBreakdown().getNetLiquidatingValue()).isCloseTo(0, offset(1e-8));
  }

  @Test
  @Order(10)
  public void test_calculate_marginDetail() throws Exception {
    assumeTrue(valDate != null);
    MarginCalcRequest request = MarginCalcRequest.builder()
        .calculationTypes(MarginCalcType.MARGIN_DETAIL)
        .valuationDate(valDate)
        .reportingCurrency("GBP")
        .portfolioData(PORTFOLIO)
        .build();
    MarginCalcResult result = marginClient.calculate(Ccp.LCH, request);
    assertThat(result.getStatus()).isEqualTo(MarginCalcResultStatus.COMPLETED);
    assertThat(result.getType()).isEqualTo(MarginCalcRequestType.STANDARD);
    assertThat(result.getCalculationTypes()).isEqualTo(set(MarginCalcType.MARGIN_DETAIL));
    assertThat(result.getValuationDate()).isEqualTo(valDate);
    assertThat(result.getReportingCurrency()).isEqualTo("GBP");
    assertThat(result.getCalculationCurrency()).isEqualTo("GBP");
    assertThat(result.getMode()).isEqualTo(MarginCalcMode.SPOT);
    assertThat(result.getPortfolioItems()).hasSize(0);
    assertThat(result.getMargin().isPresent()).isFalse();
    assertThat(result.getMarginDetail().isPresent()).isTrue();
    assertThat(result.getTradeValuations().isPresent()).isFalse();

    LchMarginDetail margin = (LchMarginDetail) result.getMarginDetail().get();
    assertThat(margin.getCcp()).isEqualTo(Ccp.LCH);
    assertThat(margin.getTotalMargin() != 0).isTrue();
    assertThat(margin.getBaseScenarioIds()).hasSize(6);
    assertThat(margin.getIndices().size() > 2).isTrue();
    LchMarginIndex index = margin.getIndices().get(0);
    assertThat(index.getIndexName().length() > 4).isTrue();
    assertThat(index.getDiversifiedBaseMargin() != 0).isTrue();
    assertThat(index.getUndiversifiedBaseMargin() != 0).isTrue();
    assertThat(index.getIndexScenarioIds()).hasSize(6);
    assertThat(margin.getScenarios().size() >= 6).isTrue();
    LchMarginScenario scenario = margin.getScenarios().get(0);
    assertThat(scenario.getId().length() > 0).isTrue();
    assertThat(scenario.getScaledPortfolioPnl() != 0).isTrue();
    assertThat(scenario.getUnscaledPortfolioPnl() != 0).isTrue();
  }

  @Test
  @Order(10)
  public void test_calculate_pv() throws Exception {
    assumeTrue(valDate != null);
    MarginCalcRequest request = MarginCalcRequest.builder()
        .calculationTypes(MarginCalcType.PRESENT_VALUE, MarginCalcType.DELTA)
        .valuationDate(valDate)
        .reportingCurrency("GBP")
        .portfolioData(PORTFOLIO)
        .build();
    MarginCalcResult result = marginClient.calculate(Ccp.LCH, request);
    assertThat(result.getStatus()).isEqualTo(MarginCalcResultStatus.COMPLETED);
    assertThat(result.getType()).isEqualTo(MarginCalcRequestType.STANDARD);
    assertThat(result.getCalculationTypes()).isEqualTo(set(MarginCalcType.PRESENT_VALUE, MarginCalcType.DELTA));
    assertThat(result.getValuationDate()).isEqualTo(valDate);
    assertThat(result.getReportingCurrency()).isEqualTo("GBP");
    assertThat(result.getCalculationCurrency()).isEqualTo("GBP");
    assertThat(result.getMode()).isEqualTo(MarginCalcMode.SPOT);
    assertThat(result.getPortfolioItems()).hasSize(0);
    assertThat(result.getMargin().isPresent()).isFalse();
    assertThat(result.getMarginDetail().isPresent()).isFalse();
    assertThat(result.getTradeValuations().isPresent()).isTrue();

    TradeValuations vals = result.getTradeValuations().get();
    assertThat(vals.getTotalPresentValue() != 0).isTrue();
    assertThat(vals.getTotalDelta().isPresent()).isTrue();
    assertThat(vals.getBucketedDelta().isPresent()).isTrue();
    assertThat(vals.getTotalGamma().isPresent()).isFalse();
    assertThat(vals.getBucketedGamma().isPresent()).isFalse();
    assertThat(vals.getTotalDelta().getAsDouble() != 0).isTrue();
    assertThat(vals.getBucketedDelta().get()).hasSize(3);
    assertThat(vals.getTrades()).hasSize(4);
    TradeValuation val = vals.getTrades().get(0);
    assertThat(val.getValue().isPresent()).isTrue();
    assertThat(val.getDelta().isPresent()).isTrue();
    assertThat(val.getGamma().isPresent()).isFalse();
    TradeValue value = val.getValue().get();