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;
  }
  protected String buildInLineCalculatedFieldClause(
      String operator,
      Operand leftOperand,
      boolean isPromptable,
      Operand rightOperand,
      Query query,
      Map entityAliasesMaps,
      IConditionalOperator conditionalOperator) {
    String[] rightOperandElements;

    logger.debug("IN");
    try {
      // Se sono qui è perchè il leftOperand è un campo calcolato inline quindi posso parserizzare
      // senza problemi
      JSONObject leftOperandJSON = new JSONObject(leftOperand.values[0]);

      String expression = leftOperandJSON.getString("expression");
      String type = leftOperandJSON.optString("type");
      if (type == null) {
        type = "STRING";
      }
      String nature = leftOperandJSON.optString("nature");
      if (nature == null) {
        nature = "ATTRIBUTE";
      }
      String alias = leftOperandJSON.optString("alias");
      if (alias == null) {
        alias = "";
      }

      String slots = null;
      String s = leftOperandJSON.optString("slots");
      if (s != null && s.trim().length() > 0) {
        slots = leftOperandJSON.getString("slots");
      }

      expression =
          parseInLinecalculatedField(
              new InLineCalculatedSelectField(
                  alias, expression, slots, type, nature, true, true, false, "", ""),
              slots,
              query,
              entityAliasesMaps);

      if (parentStatement.OPERAND_TYPE_STATIC.equalsIgnoreCase(rightOperand.type) && isPromptable) {
        // get last value first (the last value edited by the user)
        rightOperandElements = rightOperand.lastValues;
      } else {
        rightOperandElements = buildOperand(rightOperand, query, entityAliasesMaps);
      }

      if (parentStatement.OPERAND_TYPE_STATIC.equalsIgnoreCase(rightOperand.type)
          && slots == null) {
        rightOperandElements =
            getTypeBoundedStaticOperand(leftOperand, operator, rightOperandElements);
      } else {
        rightOperandElements = getTypeBoundedStaticOperand("STRING", rightOperandElements);
      }

      String operandElement = null;
      if (leftOperand instanceof HavingField.Operand) {
        HavingField.Operand havingFieldOperand = (HavingField.Operand) leftOperand;
        IAggregationFunction function = havingFieldOperand.function;
        operandElement = function.apply("(" + expression + ")");
      } else {
        operandElement = "(" + expression + ")";
      }

      return conditionalOperator.apply(operandElement, rightOperandElements);

    } catch (Throwable t) {
      throw new RuntimeException("Impossible to build inline calculated field clause", t);
    }
  }