/**
  * Add the widget value to evaluate to the Map of expression to evaluated
  *
  * @param formWidget the widget
  * @param expressionsToEvaluate the list of expressions to evaluate
  * @param context the context including the URL parameters
  */
 protected void addFormWidgetValueExpressionToEvaluate(
     final FormWidget formWidget,
     final List<Expression> expressionsToEvaluate,
     final Map<String, Object> context) {
   if (formWidget.getInitialValueExpression() != null) {
     final Expression expression = formWidget.getInitialValueExpression();
     expression.setName(formWidget.getId() + EXPRESSION_KEY_SEPARATOR + WIDGET_INITIAL_VALUE);
     expressionsToEvaluate.add(expression);
   } else if (WidgetType.EDITABLE_GRID.equals(formWidget.getType())
       && formWidget.getInitialValueExpressionArray() != null) {
     final List<List<Expression>> expressionArray = formWidget.getInitialValueExpressionArray();
     if (!expressionArray.isEmpty()) {
       int expressionArrayRowIndex = 0;
       for (final List<Expression> expressionArrayRow : expressionArray) {
         int expressionArrayIndex = 0;
         for (final Expression expression : expressionArrayRow) {
           expression.setName(
               formWidget.getId()
                   + EXPRESSION_KEY_SEPARATOR
                   + WIDGET_INITIAL_VALUE
                   + expressionArrayRowIndex
                   + INDEX_SEPARATOR
                   + expressionArrayIndex);
           expressionsToEvaluate.add(expression);
           expressionArrayIndex++;
         }
         expressionArrayRowIndex++;
       }
     }
   }
 }
 /**
  * @param formWidget
  * @param evaluatedExpressions
  * @return
  */
 protected Object getFormWidgetInitialValues(
     final FormWidget formWidget, final Map<String, Serializable> evaluatedExpressions) {
   final String widgetId = formWidget.getId();
   Object value = null;
   if (WidgetType.EDITABLE_GRID.equals(formWidget.getType())
       && evaluatedExpressions.containsKey(
           widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_INITIAL_VALUE + 0 + INDEX_SEPARATOR + 0)) {
     final List<List<Object>> initialValue = new ArrayList<List<Object>>();
     int initialValueRowIndex = 0;
     do {
       final List<Object> initialValueRow = new ArrayList<Object>();
       int initialValueColumnIndex = 0;
       do {
         final Object initialValueCell =
             evaluatedExpressions.get(
                 widgetId
                     + EXPRESSION_KEY_SEPARATOR
                     + WIDGET_INITIAL_VALUE
                     + initialValueRowIndex
                     + INDEX_SEPARATOR
                     + initialValueColumnIndex);
         initialValueRow.add(initialValueCell);
         initialValueColumnIndex++;
       } while (evaluatedExpressions.containsKey(
           widgetId
               + EXPRESSION_KEY_SEPARATOR
               + WIDGET_INITIAL_VALUE
               + initialValueRowIndex
               + INDEX_SEPARATOR
               + initialValueColumnIndex));
       initialValue.add(initialValueRow);
       initialValueRowIndex++;
     } while (evaluatedExpressions.containsKey(
         widgetId
             + EXPRESSION_KEY_SEPARATOR
             + WIDGET_INITIAL_VALUE
             + initialValueRowIndex
             + INDEX_SEPARATOR
             + 0));
     value = initialValue;
   } else {
     value = evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_INITIAL_VALUE);
   }
   return value;
 }
 /**
  * Set the tables parameters
  *
  * @param formWidget the widget
  * @param evaluatedExpressions the map of evaluated expressions
  * @param context the context including the URL parameters
  * @throws FormNotFoundException
  * @throws FormServiceProviderNotFoundException
  */
 @SuppressWarnings("unchecked")
 public void setTablesParams(
     final FormWidget formWidget,
     final Map<String, Serializable> evaluatedExpressions,
     final Map<String, Object> context)
     throws FormNotFoundException, FormServiceProviderNotFoundException {
   final String widgetId = formWidget.getId();
   if (WidgetType.TABLE.equals(formWidget.getType())
       || WidgetType.EDITABLE_GRID.equals(formWidget.getType())) {
     final Object valueColumnIndex =
         evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_VALUE_COLUMN_INDEX);
     if (valueColumnIndex != null) {
       try {
         formWidget.setValueColumnIndex((Integer) valueColumnIndex);
       } catch (final Exception e) {
         if (LOGGER.isLoggable(Level.WARNING)) {
           LOGGER.log(
               Level.WARNING,
               "The max number of columns has to be set with an integer or a groovy expression returning an integer.");
         }
         formWidget.setValueColumnIndex(0);
       }
     }
     final Object maxColumns =
         evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MAX_COLUMNS);
     if (maxColumns != null) {
       try {
         formWidget.setMaxColumns((Integer) maxColumns);
       } catch (final Exception e) {
         if (LOGGER.isLoggable(Level.WARNING)) {
           LOGGER.log(
               Level.WARNING,
               "The max number of columns has to be set with an integer or a groovy expression returning an integer.");
         }
         formWidget.setMaxColumns(-1);
       }
     } else {
       formWidget.setMaxColumns(-1);
     }
     final Object minColumns =
         evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MIN_COLUMNS);
     if (minColumns != null) {
       try {
         formWidget.setMinColumns((Integer) minColumns);
       } catch (final Exception e) {
         if (LOGGER.isLoggable(Level.WARNING)) {
           LOGGER.log(
               Level.WARNING,
               "The min number of columns has to be set with an integer or a groovy expression returning an integer.");
         }
         formWidget.setMinColumns(-1);
       }
     } else {
       formWidget.setMinColumns(-1);
     }
     final Object maxRows =
         evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MAX_ROWS);
     if (maxRows != null) {
       try {
         formWidget.setMaxRows((Integer) maxRows);
       } catch (final Exception e) {
         if (LOGGER.isLoggable(Level.WARNING)) {
           LOGGER.log(
               Level.WARNING,
               "The max number of rows has to be set with an integer or a groovy expression returning an integer.");
         }
         formWidget.setMaxRows(-1);
       }
     } else {
       formWidget.setMaxRows(-1);
     }
     final Object minRows =
         evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MIN_ROWS);
     if (minRows != null) {
       try {
         formWidget.setMinRows((Integer) minRows);
       } catch (final Exception e) {
         if (LOGGER.isLoggable(Level.WARNING)) {
           LOGGER.log(
               Level.WARNING,
               "The max number of rows has to be set with an integer or a groovy expression returning an integer.");
         }
         formWidget.setMinRows(-1);
       }
     } else {
       formWidget.setMinRows(-1);
     }
     final Object verticalHeader =
         evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_VERTICAL_HEADER);
     List<String> verticalHeaderList = null;
     if (verticalHeader != null) {
       try {
         verticalHeaderList = new ArrayList<String>((Collection<String>) verticalHeader);
       } catch (final ClassCastException e) {
         if (LOGGER.isLoggable(Level.SEVERE)) {
           LOGGER.log(
               Level.SEVERE,
               "The vertical header expression for widget "
                   + formWidget.getId()
                   + " should return a Collection.",
               e);
         }
       }
     } else if (evaluatedExpressions.containsKey(
         widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_VERTICAL_HEADER + 0)) {
       verticalHeaderList = new ArrayList<String>();
       int verticalHeaderIndex = 0;
       do {
         final Object verticalHeaderCell =
             evaluatedExpressions.get(
                 widgetId
                     + EXPRESSION_KEY_SEPARATOR
                     + WIDGET_VERTICAL_HEADER
                     + verticalHeaderIndex);
         try {
           verticalHeaderList.add((String) verticalHeaderCell);
         } catch (final ClassCastException e) {
           if (LOGGER.isLoggable(Level.SEVERE)) {
             LOGGER.log(
                 Level.SEVERE,
                 "All the vertical header expressions for widget "
                     + formWidget.getId()
                     + " should return a String.",
                 e);
           }
         }
         verticalHeaderIndex++;
       } while (evaluatedExpressions.containsKey(
           widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_VERTICAL_HEADER + verticalHeaderIndex));
     }
     formWidget.setVerticalHeader(verticalHeaderList);
     final Object horizontalHeader =
         evaluatedExpressions.get(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_HORIZONTAL_HEADER);
     List<String> horizontalHeaderList = null;
     if (horizontalHeader != null) {
       try {
         horizontalHeaderList = new ArrayList<String>((Collection<String>) horizontalHeader);
       } catch (final ClassCastException e) {
         if (LOGGER.isLoggable(Level.SEVERE)) {
           LOGGER.log(
               Level.SEVERE,
               "The horizontal header expression for widget "
                   + formWidget.getId()
                   + " should return a Collection.",
               e);
         }
       }
     } else if (evaluatedExpressions.containsKey(
         widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_HORIZONTAL_HEADER + 0)) {
       horizontalHeaderList = new ArrayList<String>();
       int horizontalHeaderIndex = 0;
       do {
         final Object horizontalHeaderCell =
             evaluatedExpressions.get(
                 widgetId
                     + EXPRESSION_KEY_SEPARATOR
                     + WIDGET_HORIZONTAL_HEADER
                     + horizontalHeaderIndex);
         try {
           horizontalHeaderList.add((String) horizontalHeaderCell);
         } catch (final ClassCastException e) {
           if (LOGGER.isLoggable(Level.SEVERE)) {
             LOGGER.log(
                 Level.SEVERE,
                 "All the horizontal header expressions for widget "
                     + formWidget.getId()
                     + " should return a String.",
                 e);
           }
         }
         horizontalHeaderIndex++;
       } while (evaluatedExpressions.containsKey(
           widgetId
               + EXPRESSION_KEY_SEPARATOR
               + WIDGET_HORIZONTAL_HEADER
               + horizontalHeaderIndex));
     }
     formWidget.setHorizontalHeader(horizontalHeaderList);
   }
 }
  /**
   * Generate the Map of groovy expressions to evaluate for a widget
   *
   * @param formWidget the widget
   * @param context the context including the URL parameters
   * @return the Map of expressions to evaluate
   */
  protected List<Expression> getWidgetExpressions(
      final FormWidget formWidget, final Map<String, Object> context) {
    final String widgetId = formWidget.getId();
    final List<Expression> expressionsToEvaluate = new ArrayList<Expression>();
    if (formWidget.getLabelExpression() != null) {
      final Expression labelExpression = formWidget.getLabelExpression();
      labelExpression.setName(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_LABEL);
      expressionsToEvaluate.add(labelExpression);
    }
    if (formWidget.getTitleExpression() != null) {
      final Expression titleExpression = formWidget.getTitleExpression();
      titleExpression.setName(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_TITLE);
      expressionsToEvaluate.add(titleExpression);
    }
    if (formWidget.getSubtitle() != null) {
      final Expression subtitleLabelExpression = formWidget.getSubtitle().getLabelExpression();
      if (subtitleLabelExpression != null) {
        subtitleLabelExpression.setName(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_SUBTITLE);
        expressionsToEvaluate.add(subtitleLabelExpression);
      }
    }
    if (formWidget.getPopupTooltipExpression() != null) {
      final Expression popupToolTipExpression = formWidget.getPopupTooltipExpression();
      popupToolTipExpression.setName(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_TOOLTIP);
      expressionsToEvaluate.add(popupToolTipExpression);
    }
    addFormWidgetValueExpressionToEvaluate(formWidget, expressionsToEvaluate, context);
    addFormWidgetAvailableValuesExpressions(formWidget, expressionsToEvaluate);

    if (WidgetType.TABLE.equals(formWidget.getType())
        || WidgetType.EDITABLE_GRID.equals(formWidget.getType())) {
      if (formWidget.getValueColumnIndexExpression() != null) {
        final Expression valueColumnIndexExpression = formWidget.getValueColumnIndexExpression();
        valueColumnIndexExpression.setName(
            widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_VALUE_COLUMN_INDEX);
        expressionsToEvaluate.add(valueColumnIndexExpression);
      }
      if (formWidget.getMaxColumnsExpression() != null) {
        final Expression valueColumnIndexExpression = formWidget.getMaxColumnsExpression();
        valueColumnIndexExpression.setName(
            widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MAX_COLUMNS);
        expressionsToEvaluate.add(valueColumnIndexExpression);
      }
      if (formWidget.getMinColumnsExpression() != null) {
        final Expression minColumnsExpression = formWidget.getMinColumnsExpression();
        minColumnsExpression.setName(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MIN_COLUMNS);
        expressionsToEvaluate.add(minColumnsExpression);
      }
      if (formWidget.getMaxRowsExpression() != null) {
        final Expression maxRowsExpression = formWidget.getMaxRowsExpression();
        maxRowsExpression.setName(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MAX_ROWS);
        expressionsToEvaluate.add(maxRowsExpression);
      }
      if (formWidget.getMinRowsExpression() != null) {
        final Expression minRowsExpression = formWidget.getMinRowsExpression();
        minRowsExpression.setName(widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_MIN_ROWS);
        expressionsToEvaluate.add(minRowsExpression);
      }
      if (formWidget.getVerticalHeaderExpression() != null) {
        final Expression verticalHeaderExpression = formWidget.getVerticalHeaderExpression();
        verticalHeaderExpression.setName(
            widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_VERTICAL_HEADER);
        expressionsToEvaluate.add(verticalHeaderExpression);
      } else if (formWidget.getVerticalHeaderExpressionList() != null) {
        final List<Expression> verticalHeaderExpressionList =
            formWidget.getVerticalHeaderExpressionList();
        if (!verticalHeaderExpressionList.isEmpty()) {
          int verticalHeaderExpressionListIndex = 0;
          for (final Expression expression : verticalHeaderExpressionList) {
            expression.setName(
                widgetId
                    + EXPRESSION_KEY_SEPARATOR
                    + WIDGET_VERTICAL_HEADER
                    + verticalHeaderExpressionListIndex);
            expressionsToEvaluate.add(expression);
            verticalHeaderExpressionListIndex++;
          }
        }
      }
      if (formWidget.getHorizontalHeaderExpression() != null) {
        final Expression horizontalHeaderExpression = formWidget.getHorizontalHeaderExpression();
        horizontalHeaderExpression.setName(
            widgetId + EXPRESSION_KEY_SEPARATOR + WIDGET_HORIZONTAL_HEADER);
        expressionsToEvaluate.add(horizontalHeaderExpression);
      } else if (formWidget.getHorizontalHeaderExpressionList() != null) {
        final List<Expression> horizontalHeaderExpressionList =
            formWidget.getHorizontalHeaderExpressionList();
        if (!horizontalHeaderExpressionList.isEmpty()) {
          int horizontalHeaderExpressionListIndex = 0;
          for (final Expression expression : horizontalHeaderExpressionList) {
            expression.setName(
                widgetId
                    + EXPRESSION_KEY_SEPARATOR
                    + WIDGET_HORIZONTAL_HEADER
                    + horizontalHeaderExpressionListIndex);
            expressionsToEvaluate.add(expression);
            horizontalHeaderExpressionListIndex++;
          }
        }
      }
    }
    return expressionsToEvaluate;
  }