public long getTotal(int maxInputList) throws SQLException, I2B2Exception {

    IInputOptionListHandler inputOptionListHandler =
        PDOFactory.buildInputListHandler(inputList, dataSourceLookup);
    // inputList.getPatientList().setMax(maxInputList);
    int minIndex = inputOptionListHandler.getMinIndex();
    inputOptionListHandler.setMaxIndex(minIndex + maxInputList);

    // iterate the panel and call total
    IFactRelatedQueryHandler factRelatedHandler = null;
    String countSqlFrom = " ";
    String countClause = " COUNT(*) ";
    if (dataSourceLookup.getServerType().equalsIgnoreCase(DAOFactoryHelper.ORACLE)
        || dataSourceLookup.getServerType().equalsIgnoreCase(DAOFactoryHelper.POSTGRESQL)) {
      factRelatedHandler =
          new FactRelatedQueryHandler(dataSourceLookup, inputList, filterList, outputOptionList);
    } else if (dataSourceLookup.getServerType().equalsIgnoreCase(DAOFactoryHelper.SQLSERVER)) {
      countSqlFrom = "as";
      countClause = " COUNT_BIG(*) ";
      factRelatedHandler =
          new SQLServerFactRelatedQueryHandler(
              dataSourceLookup, inputList, filterList, outputOptionList);
    }
    factRelatedHandler.setProjectParamMap(this.projectParamMap);
    factRelatedHandler.setModifierMetadataXmlMap(this.modifierMetadataXmlMap);

    FactOutputOptionType factOutputOptionType = new FactOutputOptionType();
    factOutputOptionType.setOnlykeys(true);
    outputOptionList.setObservationSet(factOutputOptionType);
    // outputOptionList.getObservationSet().setOnlykeys(true);

    // build sql for all the panel
    // DAOFactoryHelper daoFactoryHelper = new DAOFactoryHelper(
    // dataSourceLookup);

    IPageDao pageTotalDao =
        daoFactoryHelper.getDAOFactory().getPatientDataDAOFactory().getPageDAO();
    int panelCount = filterList.getPanel().size();
    List<String> panelSqlList = new ArrayList<String>(panelCount);
    List<Integer> sqlCountList = new ArrayList<Integer>(panelCount);
    long totalObservations = 0;
    for (PanelType singlePanel : filterList.getPanel()) {
      int sqlParamCount = singlePanel.getItem().size();
      if (singlePanel.getInvert() == 1) {
        sqlParamCount++;
      }

      sqlCountList.add(sqlParamCount);
      String totalSql = pageTotalDao.buildTotalSql(factRelatedHandler, singlePanel);
      if (totalSql.trim().length() == 0) {
        continue;
      }
      panelSqlList.add(
          "SELECT " + countClause + " from ( " + totalSql + " ) " + countSqlFrom + " totalsql");
    }

    totalObservations =
        pageTotalDao.getTotalForAllPanel(panelSqlList, sqlCountList, inputOptionListHandler);
    return totalObservations;
  }
  /**
   * @return
   * @throws SQLException
   * @throws I2B2Exception
   */
  public HashMap calculateMaxPageInputList() throws SQLException, I2B2Exception {
    int maxIteration = getPagingMaxIteration();
    int i = 0;
    long pageSize = getPageSize();
    boolean fitPagingFlag = false;
    HashMap returnResultMap = new HashMap();
    returnResultMap.put("PAGING_REQUIRED_FLAG", true);
    long totalObservations = 0;
    // PatientListTypeHandler patientList = new PatientListTypeHandler(
    // dataSourceLookup, inputList.getPatientList());

    IInputOptionListHandler inputOptionListHandler =
        PDOFactory.buildInputListHandler(inputList, dataSourceLookup);

    int maxInputList = inputOptionListHandler.getMaxIndex();
    int minInputList = inputOptionListHandler.getMinIndex();
    int originalMaxInputList = maxInputList;
    int inputListCount = maxInputList - minInputList;
    while (i < maxIteration) {
      totalObservations = getTotal(inputListCount);
      log.debug("Total observations for [" + inputListCount + " ] is [" + totalObservations + " ]");
      //
      if (i == 0) {
        returnResultMap.put("TOTAL_OBSERVATION", totalObservations);
      }

      // if total < page size then set max patient break
      if (checkIfFitThePage(pageSize, totalObservations)) {
        log.debug(
            "Input list size of [" + inputListCount + "] fits the page size [" + pageSize + "]");
        fitPagingFlag = true;
        if (i == 0) {
          returnResultMap.put("PAGING_REQUIRED_FLAG", false);
        }
        break;
      }

      // call paging method with page size, total observation,..
      inputListCount = pageMethod.calculateListSize(inputListCount, totalObservations, pageSize);

      if (inputListCount < 1) {
        // need not continue the iteration if the list size is reduced
        // to < 1
        break;
      }
      i++;
    }

    if (fitPagingFlag) {
      returnResultMap.put("MAX_INPUT_LIST", inputListCount);
      return returnResultMap;
    } else {
      throw new I2B2Exception("Could not fit in a page after [" + maxIteration + "] iteration");
    }

    /*
     * // try with minimum percent of patient int minIndex =
     * patientList.getMinIndex(); int maxIndex = originalMaxInputList; int
     * listLength = maxIndex - minIndex; int minPercentInput =
     * getMinPercentInput(listLength);
     * log.debug("Trying with minimum input list percent of [ " +
     * minPercentInput + "]");
     *
     * if (minPercentInput > 0) { if (minPercentInput < maxInputList) {
     * totalObservations = getTotal(minPercentInput); log
     * .debug("Total observations for minimum input list percent  [" +
     * minPercentInput + " ] is [" + totalObservations + " ]"); if
     * (totalObservations > 0 && checkIfFitThePage(pageSize,
     * totalObservations)) { maxInputList = minIndex + minPercentInput;
     * returnResultMap.put("MAX_INPUT_LIST", maxInputList); return
     * returnResultMap; } } } else { log
     * .debug("Skipping minimum input list percent, since the value is 0");
     * }
     */

    // try with minimun of single patient
    // int minPagingSize = getPagingMinSize();
    // log.debug("Trying with minimum input list size of [" + minPagingSize
    // + "]");
    // if (minPagingSize < 1) {
    // throw new I2B2DAOException(
    // "Paging failed, minimum page size should not be less than 1");
    // }
    //
    // HashMap minMap = getMinPatientIndexAndTheTotal(originalMaxInputList);
    // int minDataIndex = (Integer) minMap.get("MIN_INDEX");
    // long minDataIndexTotal = (Long) minMap.get("MIN_INDEX_TOTAL");
    //
    // System.out.println("min index" + minMap.get("MIN_INDEX"));
    // System.out.println("min index total " +
    // minMap.get("MIN_INDEX_TOTAL"));
    //
    // // totalObservations = getTotal(minPagingSize);
    // log.debug("Total observation for first data index [" + minDataIndex
    // + " ] is [" + minDataIndexTotal + "]");
    //
    // if (!checkIfFitThePage(pageSize, minDataIndexTotal)) {
    // throw new I2B2DAOException(
    // "Paging failed, even the first patient index of ["
    // + minDataIndex + "] patient observations ["
    // + minDataIndexTotal
    // + "] could not fit the page size [" + pageSize
    // + "]");
    // } else {
    //
    // returnResultMap.put("MAX_INPUT_LIST", minDataIndex);
    // return returnResultMap;
    // }
  }
  public HashMap getMinPatientIndexAndTheTotal(int maxInputList)
      throws SQLException, I2B2Exception {

    IInputOptionListHandler inputOptionListHandler =
        PDOFactory.buildInputListHandler(inputList, dataSourceLookup);

    // inputList.getPatientList().setMax(maxInputList);
    inputOptionListHandler.setMaxIndex(maxInputList);

    // iterate the panel and call total
    IFactRelatedQueryHandler factRelatedHandler = null;
    String countSqlFrom = " ";
    if (dataSourceLookup.getServerType().equalsIgnoreCase(DAOFactoryHelper.ORACLE)
        || dataSourceLookup.getServerType().equalsIgnoreCase(DAOFactoryHelper.POSTGRESQL)) {
      factRelatedHandler =
          new FactRelatedQueryHandler(dataSourceLookup, inputList, filterList, outputOptionList);
    } else if (dataSourceLookup.getServerType().equalsIgnoreCase(DAOFactoryHelper.SQLSERVER)) {
      countSqlFrom = "as";
      factRelatedHandler =
          new SQLServerFactRelatedQueryHandler(
              dataSourceLookup, inputList, filterList, outputOptionList);
    }
    // set project param
    factRelatedHandler.setProjectParamMap(this.projectParamMap);
    factRelatedHandler.setModifierMetadataXmlMap(this.modifierMetadataXmlMap);

    FactOutputOptionType factOutputOptionType = new FactOutputOptionType();
    factOutputOptionType.setOnlykeys(true);
    outputOptionList.setObservationSet(factOutputOptionType);
    // outputOptionList.getObservationSet().setOnlykeys(true);

    // build sql for all the panel
    // DAOFactoryHelper daoFactoryHelper = new DAOFactoryHelper(
    // dataSourceLookup);

    IPageDao pageTotalDao =
        daoFactoryHelper.getDAOFactory().getPatientDataDAOFactory().getPageDAO();
    int panelCount = filterList.getPanel().size();
    List<String> panelMinSqlList = new ArrayList<String>(panelCount);
    List<Integer> sqlCountList = new ArrayList<Integer>(panelCount);
    long totalObservations = 0;
    // things to consider to find the minimum
    // a)How to handle the different input list (i.e. enumeration list,table
    // or patient_dimension)

    String panelSql = "";
    for (PanelType singlePanel : filterList.getPanel()) {
      int sqlParamCount = singlePanel.getItem().size();
      if (singlePanel.getInvert() == 1) {
        sqlParamCount++;
      }
      if (inputOptionListHandler.isCollectionId()) {
        sqlParamCount++;
      }

      sqlCountList.add(sqlParamCount);

      panelSql = pageTotalDao.buildTotalSql(factRelatedHandler, singlePanel);
      if (panelSql.length() == 0) {
        continue;
      }
      String minSql = inputOptionListHandler.generateMinIndexSql(panelSql);
      System.out.println("min sql for panel " + minSql);
      panelMinSqlList.add(minSql);
    }

    return pageTotalDao.getMinIndexAndCountAllPanel(
        panelMinSqlList, sqlCountList, inputOptionListHandler);
  }