/**
   * Advanced checking of an expression, needed because Expression.fromString() might terminate
   * normally, but returned Expression will not be appliable for real Entities. Current
   * implementation assures all attributes in expression are present in Entity
   *
   * @param root Root of a query
   * @param ex Expression to check
   * @throws ValidationException when something's wrong
   */
  static void checkExpression(Entity root, Expression ex) throws ValidationException {
    try {
      if (ex instanceof ASTPath) {
        /**
         * Try to iterate through path, if some attributes are not present, exception will be raised
         */
        Iterator<CayenneMapEntry> path = root.resolvePathComponents(ex);
        while (path.hasNext()) {
          path.next();
        }
      }

      if (ex != null) {
        for (int i = 0; i < ex.getOperandCount(); i++) {
          if (ex.getOperand(i) instanceof Expression) {
            checkExpression(root, (Expression) ex.getOperand(i));
          }
        }
      }
    } catch (ExpressionException eex) {
      throw new ValidationException(eex.getUnlabeledMessage());
    }
  }