/**
 * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.analytics.financial.interestrate.bond.calculator;

import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitorAdapter;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondCapitalIndexedSecurity;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondCapitalIndexedTransaction;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedSecurity;
import com.opengamma.analytics.financial.interestrate.bond.provider.BondCapitalIndexedSecurityDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.bond.provider.BondSecurityDiscountingMethod;
import com.opengamma.util.ArgumentChecker;

/**
 * Calculate accrued interest from clean price.
 */
public final class AccruedInterestFromCleanPriceCalculator extends InstrumentDerivativeVisitorAdapter<Double, Double> {

  /**
   * The calculator instance.
   */
  private static final AccruedInterestFromCleanPriceCalculator s_instance = new AccruedInterestFromCleanPriceCalculator();

  /**
   * Return the calculator instance.
   * @return The instance.
   */
  public static AccruedInterestFromCleanPriceCalculator getInstance() {
    return s_instance;
  }

  /**
   * Private constructor.
   */
  private AccruedInterestFromCleanPriceCalculator() {
  }

  /**
   * The method used for different instruments.
   */
  private static final BondSecurityDiscountingMethod METHOD_BOND_SECURITY = BondSecurityDiscountingMethod.getInstance();
  private static final BondCapitalIndexedSecurityDiscountingMethod METHOD_INFLATION_BOND_SECURITY = BondCapitalIndexedSecurityDiscountingMethod.getInstance();

  @Override
  public Double visitBondFixedSecurity(final BondFixedSecurity bond, final Double price) {
    return METHOD_BOND_SECURITY.accruedInterestFromCleanPrice(bond, price);
  }

  @Override
  public Double visitBondCapitalIndexedTransaction(final BondCapitalIndexedTransaction bond, final Double cleanPrice) {
    ArgumentChecker.notNull(bond, "bond");
    ArgumentChecker.notNull(cleanPrice, "yield");
    ArgumentChecker.notNull(bond.getBondStandard() instanceof BondCapitalIndexedSecurity<?>, "the bond should be a BondCapitalIndexedSecurity");

    final BondCapitalIndexedSecurity<?> bondSecurity = (BondCapitalIndexedSecurity<?>) bond.getBondStandard();
    return METHOD_INFLATION_BOND_SECURITY.accruedInterestFromCleanRealPrice(bondSecurity, cleanPrice);
  }

}

@@ -204,16 +204,114 @@
 lator;%0A%0A
+import static com.opengamma.financial.convention.yield.SimpleYieldConvention.INDEX_LINKED_FLOAT;%0A%0A
 import c
@@ -672,32 +672,124 @@
 dFixedSecurity;%0A
+import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedTransaction;%0A
 import com.openg
@@ -1681,26 +1681,35 @@
 r di
-ffere
+scou
 nt
- 
 in
-strument
+g the bond cashflow
 s.%0A 
@@ -1834,16 +1834,95 @@
 ance();%0A
+  /**%0A   * The method used for discounting the inflation bond cashflows.%0A   */%0A
   privat
@@ -2171,17 +2171,22 @@
 ble 
-p
+cleanP
 rice) %7B%0A
     
@@ -2177,24 +2177,122 @@
 eanPrice) %7B%0A
+    ArgumentChecker.notNull(bond, %22bond%22);%0A    ArgumentChecker.notNull(cleanPrice, %22cleanPrice%22);%0A
     return M
@@ -2351,20 +2351,33 @@
 nd, 
-price)
+cleanPrice) * 100
 ;%0A  %7D%0A
+  
 %0A  @
@@ -2414,81 +2414,249 @@
 Bond
-CapitalIndexedTransaction(final BondCapitalIndexedTransaction bond, final
+FixedTransaction(BondFixedTransaction bond, Double cleanPrice) %7B%0A    return visitBondFixedSecurity(bond.getBondTransaction(), cleanPrice);%0A  %7D%0A  %0A  @Override%0A  public Double visitBondCapitalIndexedSecurity(BondCapitalIndexedSecurity%3C?%3E bond,
  Dou
@@ -2656,32 +2656,36 @@
 nd, Double clean
+Real
 Price) %7B%0A    Arg
@@ -2745,32 +2745,36 @@
 er.notNull(clean
+Real
 Price, %22yield%22);
@@ -2778,39 +2778,543 @@
 %22);%0A    
-ArgumentChecker.notNull
+double accruedInterest = METHOD_INFLATION_BOND_SECURITY.accruedInterestFromCleanRealPrice(bond, cleanRealPrice) * 100;%0A    if (bond.getYieldConvention().equals(INDEX_LINKED_FLOAT)) %7B%0A      return accruedInterest * bond.getIndexRatio();%0A    %7D else %7B%0A      return accruedInterest;%0A    %7D%0A  %7D%0A%0A  @Override%0A  public Double visitBondCapitalIndexedTransaction(final BondCapitalIndexedTransaction%3C?%3E bond, final Double cleanPrice) %7B%0A    ArgumentChecker.notNull(bond, %22bond%22);%0A    ArgumentChecker.notNull(cleanPrice, %22yield%22);%0A    if (!
 (bond.ge
@@ -3373,16 +3373,56 @@
 y%3C?%3E
-, %22the b
+)) %7B%0A      throw new IllegalArgumentException(%22B
 ond 
@@ -3463,16 +3463,21 @@
 rity%22);%0A
+    %7D
 %0A    fin
@@ -3595,72 +3595,39 @@
 urn 
-METHOD_INFLATION_BOND_SECURITY.accruedInterestFromCleanRealPrice
+visitBondCapitalIndexedSecurity
 (bon

Fix scaling accrued interest to 100 par value and whether to return the nominal or real amount