public boolean hasRegistryTotalLines() {
   Iterator<Column> it = registryConfig.getColumns().iterator();
   boolean found = false;
   while (it.hasNext() && !found) {
     Column column = it.next();
     String sfO = column.getSummaryFunction();
     if (sfO != null && sfO.equalsIgnoreCase("sum")) {
       found = true;
     }
   }
   return found;
 }
  private void changeAlias(IDataStore dataStore) {
    logger.debug("IN");
    IMetaData metaData = dataStore.getMetaData();

    for (int i = 0; i < metaData.getFieldCount(); i++) {
      IFieldMetaData meta = metaData.getFieldMeta(i);
      Column col = registryConfig.getColumnConfiguration(meta.getAlias());
      if (col.getTitle() != null) {
        meta.setAlias(col.getTitle());
        // metaData.changeFieldAlias(i, col.getTitle());
        logger.debug("Changed alias of column " + meta.getName() + " to " + col.getTitle());
      }
    }

    logger.debug("OUT");
  }
  private void getMandatoryMetadata(Column column) {
    try {
      // mandatory management
      String mandatoryColumn = column.getMandatoryColumn();
      String mandatoryValue = column.getMandatoryValue();
      JSONObject mandatory = new JSONObject();

      if (mandatoryColumn != null && mandatoryValue != null) {
        mandatory.put("mandatoryColumn", mandatoryColumn);
        mandatory.put("mandatoryValue", mandatoryValue);
        mandatory.put("column", column.getField());
        mandatories.put(mandatory);
      }
    } catch (JSONException e) {
      logger.error("Error getting mandatory informations from template " + e.getMessage());
    }
  }
  private void getColumnsInfos(Column column) {
    try {
      Integer size = column.getSize();
      String sizeColumn = column.getField();
      boolean unsigned = column.isUnsigned();
      JSONObject infoObj = new JSONObject();

      infoObj.putOpt("sizeColumn", sizeColumn);
      infoObj.putOpt("size", size);

      infoObj.putOpt("unsigned", unsigned);
      if (size != null || unsigned != false) {
        columnsInfos.put(infoObj);
      }

    } catch (JSONException e) {
      logger.error("Error getting size column informations from template " + e.getMessage());
    }
  }
  private IModelField getColumnModelField(Column column, IModelEntity entity) {
    if (column.getSubEntity()
        != null) { // in case it is a subEntity attribute, look for the field inside it

      // In order to recover subentities the new way if DEFAULT_MAX_RECURSION_LEVEL is set to zero
      /*
      	QbeEngineInstance engineInstance = getEngineInstance();
      QbeTemplate template = engineInstance.getTemplate();
      // takes the only datamart's name configured
      String modelName = (String) template.getDatamartNames().get(0);
      IModelStructure md = getDataSource().getModelStructure();
      IModelEntity	subEntity  = md.getEntity(column.getSubEntity()); */

      String entityUName = entity.getUniqueName();
      String subEntityKey =
          entityUName.substring(0, entityUName.lastIndexOf("::"))
              + "::"
              + column.getSubEntity()
              + "("
              + column.getForeignKey()
              + ")";
      IModelEntity subEntity = entity.getSubEntity(subEntityKey);
      if (subEntity == null) {
        throw new SpagoBIEngineServiceException(
            getActionName(),
            "Sub-entity ["
                + column.getSubEntity()
                + "] not found in entity ["
                + entity.getName()
                + "]!");
      }
      entity = subEntity;
    }
    logger.debug(
        "Looking for attribute " + column.getField() + " in entity " + entity.getName() + " ...");
    List<IModelField> fields = entity.getAllFields();
    Iterator<IModelField> it = fields.iterator();
    while (it.hasNext()) {
      IModelField field = it.next();
      if (field.getName().equals(column.getField())) {
        return field;
      }
    }
    return null;
  }
  private Query buildQuery() {
    logger.debug("IN");
    Query query = null;
    try {
      QbeEngineInstance qbeEngineInstance = getEngineInstance();
      Map env = qbeEngineInstance.getEnv();

      query = new Query();
      query.setDistinctClauseEnabled(false);
      IModelEntity entity = getSelectedEntity();

      QbeEngineInstance engineInstance = getEngineInstance();
      QbeTemplate template = engineInstance.getTemplate();
      registryConfig = (RegistryConfiguration) template.getProperty("registryConfiguration");
      List<Column> columns = registryConfig.getColumns();
      columnMaxSize = registryConfig.getColumnsMaxSize();
      Iterator<Column> it = columns.iterator();

      Map<String, String> fieldNameIdMap = new HashMap<String, String>();

      while (it.hasNext()) {
        Column column = it.next();
        getMandatoryMetadata(column);
        getColumnsInfos(column);
        IModelField field = getColumnModelField(column, entity);
        if (field == null) {
          logger.error("Field " + column.getField() + " not found!!");
        } else {
          String name = field.getPropertyAsString("label");
          if (name == null || name.length() == 0) {
            name = field.getName();
          }

          String sorter =
              column.getSorter() != null
                      && (column.getSorter().equalsIgnoreCase("ASC")
                          || column.getSorter().equalsIgnoreCase("DESC"))
                  ? column.getSorter().toUpperCase()
                  : null;

          query.addSelectFiled(
              field.getUniqueName(),
              "NONE",
              field.getName(),
              true,
              true,
              false,
              sorter,
              field.getPropertyAsString("format"));
          fieldNameIdMap.put(column.getField(), field.getUniqueName());
        }
      }

      // get Drivers and filters

      List<RegistryConfiguration.Filter> filters = registryConfig.getFilters();
      int i = 0;
      ArrayList<ExpressionNode> expressionNodes = new ArrayList<ExpressionNode>();
      for (Iterator iterator = filters.iterator(); iterator.hasNext(); ) {
        Filter filter = (Filter) iterator.next();
        addFilter(i, query, env, fieldNameIdMap, filter, expressionNodes);
        i++;
      }
      // put together expression nodes
      if (expressionNodes.size() == 1) {
        query.setWhereClauseStructure(expressionNodes.get(0));
      } else if (expressionNodes.size() > 1) {
        ExpressionNode exprNodeAnd = new ExpressionNode("NODE_OP", "AND");
        exprNodeAnd.setChildNodes(expressionNodes);
        query.setWhereClauseStructure(exprNodeAnd);
      }

    } finally {
      logger.debug("OUT");
    }
    return query;
  }
  private void addSumRows(IDataStore dataStore) {
    logger.debug("IN");

    summaryColorCellsArray = new JSONArray();
    summaryCellsArray = new JSONArray();

    ArrayList<Integer> columnsIndexToMerge = new ArrayList<Integer>();
    ArrayList<Integer> columnsIndexToEmpty = new ArrayList<Integer>();
    ArrayList<Integer> columnsIndexToAfter = new ArrayList<Integer>();
    HashMap<Integer, Object> columnsIndexToSum2Counter = new HashMap<Integer, Object>();

    // collect columns to merge and columns to sum and colummsn to empty:
    // -- columns to merge have merge attributes until a columns with summaryFunc is found
    // then other columns that have merge attribute but no
    List<Column> columns = registryConfig.getColumns();

    Integer index = 0;
    boolean summaryFuncFound = false;
    boolean measureFound = false;

    for (Iterator iterator = columns.iterator(); iterator.hasNext(); ) {
      Column column = (Column) iterator.next();

      if (column.isMerge() && summaryFuncFound == false) {
        columnsIndexToMerge.add(index);
      } else if (summaryFuncFound == true && !column.isMeasure() && !measureFound) {
        columnsIndexToEmpty.add(index);
      } else if (summaryFuncFound == true && !column.isMeasure() && measureFound) {
        columnsIndexToAfter.add(index);
      } else if (column.isMeasure()) {
        columnsIndexToSum2Counter.put(index, 0);
        measureFound = true;
      }
      if (column.getSummaryFunction() != null && column.getSummaryFunction().equals("sum"))
        summaryFuncFound = true;
      index++;
    }

    // Map to store previous merge values on iteration
    HashMap<Integer, Object> previousMergeValues = new HashMap<Integer, Object>();
    for (Iterator iterator = columnsIndexToMerge.iterator(); iterator.hasNext(); ) {
      Integer columnIndex = (Integer) iterator.next();
      previousMergeValues.put(columnIndex, null);
    }

    TreeMap<Integer, Record> recordsToAddMap = new TreeMap<Integer, Record>();

    int sumCounter = 0; // add total row only if grouping has more than one member

    // iterate on each store row
    for (int i = 0; i < dataStore.getRecordsCount(); i++) {
      IRecord record = dataStore.getRecordAt(i);

      // get current values of column to merge
      HashMap<Integer, Object> currentMergeValues = new HashMap<Integer, Object>();

      // iterate on each column to merge and store values
      for (Iterator iterator = columnsIndexToMerge.iterator(); iterator.hasNext(); ) {
        Integer columnIndex = (Integer) iterator.next();
        Object value = record.getFieldAt(columnIndex).getValue();
        currentMergeValues.put(columnIndex, value);
      }

      // compare current values with previous ones
      boolean isEqual = compareValuesMaps(previousMergeValues, currentMergeValues);

      // if merging goes on update counters else add summarization line
      if (isEqual) {
        sumCounter++;
        for (Iterator iterator = columnsIndexToSum2Counter.keySet().iterator();
            iterator.hasNext(); ) {
          Integer indexMeasure = (Integer) iterator.next();
          Object value = record.getFieldAt(indexMeasure).getValue();

          // TODO treat the case this is not a number, should keep it to null
          if (value != null) {
            // get previous value

            Object result = operateWithNumbers(columnsIndexToSum2Counter.get(indexMeasure), value);

            columnsIndexToSum2Counter.put(indexMeasure, result);
          } else {
            columnsIndexToSum2Counter.put(indexMeasure, null);
          }
        }
      } else {
        // breaking point, add summarization lines at previous index; i-1

        // add a new record only if sumCounter > 0
        if (sumCounter > 0) {
          addTotalRecord(
              dataStore,
              i,
              columnsIndexToMerge,
              columnsIndexToEmpty,
              columnsIndexToAfter,
              columnsIndexToSum2Counter,
              previousMergeValues,
              recordsToAddMap);
        }

        // put the counters to actual values
        for (Iterator iterator = columnsIndexToSum2Counter.keySet().iterator();
            iterator.hasNext(); ) {
          Integer columnInd = (Integer) iterator.next();
          Object v = record.getFieldAt(columnInd).getValue();
          columnsIndexToSum2Counter.put(columnInd, v);
        }

        sumCounter = 0;
      }

      // update previousValues
      previousMergeValues = currentMergeValues;
    }

    // add  final total if last records were merged
    if (sumCounter > 0) {
      addTotalRecord(
          dataStore,
          null,
          columnsIndexToMerge,
          columnsIndexToEmpty,
          columnsIndexToAfter,
          columnsIndexToSum2Counter,
          previousMergeValues,
          recordsToAddMap);
    }

    // finally add the record (could not add them while cycling the store)
    for (Iterator iterator = recordsToAddMap.keySet().iterator(); iterator.hasNext(); ) {
      Integer indexR = (Integer) iterator.next();
      Record rec = recordsToAddMap.get(indexR);
      if (indexR == -1) {
        dataStore.appendRecord(rec);
      } else {
        dataStore.insertRecord(indexR, rec);
      }
    }

    logger.debug("OUT");
  }