protected String buildFieldOperand(Operand operand, Query query, Map entityAliasesMaps) {
    String operandElement;
    IModelField datamartField;
    IModelEntity rootEntity;
    String queryName;
    String rootEntityAlias;
    Map targetQueryEntityAliasesMap;

    logger.debug("IN");

    try {

      targetQueryEntityAliasesMap = (Map) entityAliasesMaps.get(query.getId());
      Assert.assertNotNull(
          targetQueryEntityAliasesMap,
          "Entity aliases map for query ["
              + query.getId()
              + "] cannot be null in order to execute method [buildUserProvidedWhereField]");

      datamartField =
          parentStatement.getDataSource().getModelStructure().getField(operand.values[0]);
      Assert.assertNotNull(
          datamartField, "DataMart does not cantain a field named [" + operand.values[0] + "]");
      Couple queryNameAndRoot = datamartField.getQueryName();

      queryName = (String) queryNameAndRoot.getFirst();
      logger.debug("select field query name [" + queryName + "]");

      if (queryNameAndRoot.getSecond() != null) {
        rootEntity = (IModelEntity) queryNameAndRoot.getSecond();
      } else {
        rootEntity = datamartField.getParent().getRoot();
      }
      logger.debug("where field query name [" + queryName + "]");

      logger.debug("where field root entity unique name [" + rootEntity.getUniqueName() + "]");

      if (!targetQueryEntityAliasesMap.containsKey(rootEntity.getUniqueName())) {
        logger.debug("Entity [" + rootEntity.getUniqueName() + "] require a new alias");
        rootEntityAlias =
            getEntityAlias(rootEntity, targetQueryEntityAliasesMap, entityAliasesMaps);
        logger.debug("A new alias has been generated [" + rootEntityAlias + "]");
      }
      rootEntityAlias = (String) targetQueryEntityAliasesMap.get(rootEntity.getUniqueName());
      logger.debug("where field root entity alias [" + rootEntityAlias + "]");

      if (operand instanceof HavingField.Operand) {
        HavingField.Operand havingFieldOperand = (HavingField.Operand) operand;
        IAggregationFunction function = havingFieldOperand.function;
        operandElement = function.apply(parentStatement.getFieldAlias(rootEntityAlias, queryName));
      } else {
        operandElement = parentStatement.getFieldAlias(rootEntityAlias, queryName);
      }
      logger.debug("where element operand value [" + operandElement + "]");
    } finally {
      logger.debug("OUT");
    }

    return operandElement;
  }
  private void addFilter(
      int i,
      Query query,
      Map env,
      Map<String, String> fieldNameIdMap,
      Filter filter,
      ArrayList<ExpressionNode> expressionNodes) {
    logger.debug("IN");

    ExpressionNode node = query.getWhereClauseStructure();
    ExpressionNode nodeToInsert = new ExpressionNode("NODE_OP", "AND");

    // in case it is a driver
    if (filter
        .getPresentationType()
        .equals(RegistryConfigurationXMLParser.PRESENTATION_TYPE_DRIVER)) {
      String driverName = filter.getDriverName();
      String fieldName = filter.getField();

      Object value = env.get(driverName);

      if (value != null && !value.toString().equals("")) {

        // TODO, change this behaviour
        if (value.toString().contains(",")) {
          value = "{,{" + value + "}}";
        }
        List valuesList = new ParametersDecoder().decode(value.toString());
        String[] valuesArr = new String[valuesList.size()];

        for (int j = 0; j < valuesList.size(); j++) {
          String val = valuesList.get(j).toString();
          valuesArr[j] = val;
        }

        logger.debug(
            "Set filter from analytical deriver "
                + driverName
                + ": "
                + filter.getField()
                + "="
                + value);

        String fieldId = fieldNameIdMap.get(fieldName);
        String[] fields = new String[] {fieldId};
        WhereField.Operand left =
            new WhereField.Operand(
                fields, "driverName", AbstractStatement.OPERAND_TYPE_SIMPLE_FIELD, null, null);

        WhereField.Operand right =
            new WhereField.Operand(
                valuesArr, "value", AbstractStatement.OPERAND_TYPE_STATIC, null, null);

        if (valuesArr.length > 1) {
          query.addWhereField(
              "Driver_" + i, driverName, false, left, CriteriaConstants.IN, right, "AND");
        } else {
          query.addWhereField(
              "Driver_" + i, driverName, false, left, CriteriaConstants.EQUALS_TO, right, "AND");
        }

        ExpressionNode newFilterNode =
            new ExpressionNode("NODE_CONST", "$F{" + "Driver_" + i + "}");
        // query.setWhereClauseStructure(newFilterNode);
        expressionNodes.add(newFilterNode);
      }

      // query.setWhereClauseStructure(whereClauseStructure)
    }
    // in case it is a filter and has a value setted
    else if (requestContainsAttribute(filter.getField())) {

      String value = getAttribute(filter.getField()).toString();
      if (value != null && !value.equalsIgnoreCase("")) {
        logger.debug("Set filter " + filter.getField() + "=" + value);

        String fieldId = fieldNameIdMap.get(filter.getField());
        String[] fields = new String[] {fieldId};
        String[] values = new String[] {value};

        WhereField.Operand left =
            new WhereField.Operand(
                fields, "filterName", AbstractStatement.OPERAND_TYPE_SIMPLE_FIELD, null, null);

        WhereField.Operand right =
            new WhereField.Operand(
                values, "value", AbstractStatement.OPERAND_TYPE_STATIC, null, null);

        // if filter type is manual use it as string starting, else as equals
        if (filter
            .getPresentationType()
            .equals(RegistryConfigurationXMLParser.PRESENTATION_TYPE_COMBO)) {
          query.addWhereField(
              "Filter_" + i,
              filter.getField(),
              false,
              left,
              CriteriaConstants.EQUALS_TO,
              right,
              "AND");
        } else {
          query.addWhereField(
              "Filter_" + i,
              filter.getField(),
              false,
              left,
              CriteriaConstants.STARTS_WITH,
              right,
              "AND");
        }

        ExpressionNode newFilterNode =
            new ExpressionNode("NODE_CONST", "$F{" + "Filter_" + i + "}");
        // query.setWhereClauseStructure(newFilterNode);
        expressionNodes.add(newFilterNode);
      }
    }
    logger.debug("OUT");
  }
  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;
  }
  protected String buildParentFieldOperand(Operand operand, Query query, Map entityAliasesMaps) {
    String operandElement;

    String[] chunks;
    String parentQueryId;
    String fieldName;
    IModelField datamartField;
    IModelEntity rootEntity;
    String queryName;
    String rootEntityAlias;

    logger.debug("IN");

    try {

      // it comes directly from the client side GUI. It is a composition of the parent query id and
      // filed name,
      // separated by a space
      logger.debug("operand  is equals to [" + operand.values[0] + "]");

      chunks = operand.values[0].split(" ");
      Assert.assertTrue(
          chunks.length >= 2,
          "Operand ["
              + chunks.toString()
              + "] does not contains enougth informations in order to resolve the reference to parent field");

      parentQueryId = chunks[0];
      logger.debug("where right-hand field belonging query [" + parentQueryId + "]");
      fieldName = chunks[1];
      logger.debug("where right-hand field unique name [" + fieldName + "]");

      datamartField = parentStatement.getDataSource().getModelStructure().getField(fieldName);
      Assert.assertNotNull(
          datamartField, "DataMart does not cantain a field named [" + fieldName + "]");

      Couple queryNameAndRoot = datamartField.getQueryName();

      queryName = (String) queryNameAndRoot.getFirst();
      logger.debug("select field query name [" + queryName + "]");

      if (queryNameAndRoot.getSecond() != null) {
        rootEntity = (IModelEntity) queryNameAndRoot.getSecond();
      } else {
        rootEntity = datamartField.getParent().getRoot();
      }
      logger.debug("where right-hand field query name [" + queryName + "]");
      logger.debug(
          "where right-hand field root entity unique name [" + rootEntity.getUniqueName() + "]");

      Map parentEntityAliases = (Map) entityAliasesMaps.get(parentQueryId);
      if (parentEntityAliases != null) {
        if (!parentEntityAliases.containsKey(rootEntity.getUniqueName())) {
          Assert.assertUnreachable(
              "Filter of subquery ["
                  + query.getId()
                  + "] refers to a non "
                  + "existing parent query ["
                  + parentQueryId
                  + "] entity ["
                  + rootEntity.getUniqueName()
                  + "]");
        }
        rootEntityAlias = (String) parentEntityAliases.get(rootEntity.getUniqueName());
      } else {
        rootEntityAlias = "unresoved_alias";
        logger.warn(
            "Impossible to get aliases map for parent query ["
                + parentQueryId
                + "]. Probably the parent query ha not been compiled yet");
        logger.warn(
            "Query ["
                + query.getId()
                + "] refers entities of its parent query ["
                + parentQueryId
                + "] so the generated statement wont be executable until the parent query will be compiled");
      }
      logger.debug("where right-hand field root entity alias [" + rootEntityAlias + "]");

      operandElement = parentStatement.getFieldAlias(rootEntityAlias, queryName);
      logger.debug("where element right-hand field value [" + operandElement + "]");
    } finally {
      logger.debug("OUT");
    }

    return operandElement;
  }