private List<EgDemandReasonDetails> getDemandReasonDetails(
     final String demandReasonCode,
     final BigDecimal grossAnnualRentAfterDeduction,
     final Installment installment) {
   return persistenceService.findAllByNamedQuery(
       QUERY_DEMANDREASONDETAILS_BY_DEMANDREASON_AND_INSTALLMENT,
       demandReasonCode,
       grossAnnualRentAfterDeduction,
       installment.getFromDate(),
       installment.getToDate());
 }
  private BoundaryCategory getBoundaryCategory(
      final Boundary zone,
      final Installment installment,
      final Long usageId,
      final Date occupancyDate) {
    List<BoundaryCategory> categories = new ArrayList<BoundaryCategory>();

    categories =
        persistenceService.findAllByNamedQuery(
            QUERY_BASERATE_BY_OCCUPANCY_ZONE,
            zone.getId(),
            usageId,
            occupancyDate,
            installment.getToDate());

    LOGGER.debug("baseRentOfUnit - Installment : " + installment);
    return categories.get(0);
  }
  /**
   * @param property Property Object
   * @param applicableTaxes List of Applicable Taxes
   * @param occupationDate Minimum Occupancy Date among all the units
   * @return
   */
  @Override
  public HashMap<Installment, TaxCalculationInfo> calculatePropertyTax(
      final Property property, final Date occupationDate) {

    Boundary propertyZone = null;
    BigDecimal totalNetArv = BigDecimal.ZERO;
    BoundaryCategory boundaryCategory = null;
    // TODO move method prepareApplicableTaxes to tax calculator
    final List<String> applicableTaxes = prepareApplicableTaxes(property);
    final List<Installment> taxInstallments = getInstallmentListByStartDate(occupationDate);
    propertyZone = property.getBasicProperty().getPropertyID().getZone();

    for (final Installment installment : taxInstallments) {
      totalTaxPayable = BigDecimal.ZERO;
      final APTaxCalculationInfo taxCalculationInfo = addPropertyInfo(property);

      if (betweenOrBefore(occupationDate, installment.getFromDate(), installment.getToDate())) {
        if (property
            .getPropertyDetail()
            .getPropertyTypeMaster()
            .getCode()
            .equals(OWNERSHIP_TYPE_VAC_LAND)) {
          final APUnitTaxCalculationInfo unitTaxCalculationInfo =
              calculateVacantLandTax(property, occupationDate);
          totalNetArv = totalNetArv.add(unitTaxCalculationInfo.getNetARV());
          taxCalculationInfo.addUnitTaxCalculationInfo(unitTaxCalculationInfo);
          calculateApplicableTaxes(
              applicableTaxes,
              unitTaxCalculationInfo,
              installment,
              property.getPropertyDetail().getPropertyTypeMaster().getCode());
          totalTaxPayable = totalTaxPayable.add(unitTaxCalculationInfo.getTotalTaxPayable());
        } else
          for (final Floor floorIF : property.getPropertyDetail().getFloorDetails())
            if (floorIF != null) {
              // TODO think about, these beans to be client
              // specific
              boundaryCategory =
                  getBoundaryCategory(
                      propertyZone,
                      installment,
                      floorIF.getPropertyUsage().getId(),
                      occupationDate);
              final APUnitTaxCalculationInfo unitTaxCalculationInfo =
                  prepareUnitCalcInfo(property, floorIF, boundaryCategory);
              totalNetArv = totalNetArv.add(unitTaxCalculationInfo.getNetARV());

              calculateApplicableTaxes(
                  applicableTaxes,
                  unitTaxCalculationInfo,
                  installment,
                  property.getPropertyDetail().getPropertyTypeMaster().getCode());

              totalTaxPayable = totalTaxPayable.add(unitTaxCalculationInfo.getTotalTaxPayable());
              taxCalculationInfo.addUnitTaxCalculationInfo(unitTaxCalculationInfo);
            }
        taxCalculationInfo.setTotalNetARV(totalNetArv);
        taxCalculationInfo.setTotalTaxPayable(totalTaxPayable);
        taxCalculationInfo.setTaxCalculationInfoXML(generateTaxCalculationXML(taxCalculationInfo));
        taxCalculationMap.put(installment, taxCalculationInfo);
      }
    }
    return taxCalculationMap;
  }