/*
   * Must be one of:
   * <ul>
   * <li>[indexBinding]++</li>
   * <li>++[indexBinding]</li>
   * <li>[indexBinding]+= 1</li>
   * <li>[indexBinding]= [indexBinding] + 1</li>
   * <li>[indexBinding]= 1 + [indexBinding]</li>
   * <ul>
   */
  private boolean validateUpdaters(ForStatement statement) {
    List<Expression> updaters = statement.updaters();
    if (updaters.size() != 1) return false;

    Expression updater = updaters.get(0);
    if (updater instanceof PostfixExpression) {
      PostfixExpression postfix = (PostfixExpression) updater;

      if (!PostfixExpression.Operator.INCREMENT.equals(postfix.getOperator())) return false;

      IBinding binding = getBinding(postfix.getOperand());
      if (!fIndexBinding.equals(binding)) return false;

      return true;
    } else if (updater instanceof PrefixExpression) {
      PrefixExpression prefix = (PrefixExpression) updater;

      if (!PrefixExpression.Operator.INCREMENT.equals(prefix.getOperator())) return false;

      IBinding binding = getBinding(prefix.getOperand());
      if (!fIndexBinding.equals(binding)) return false;

      return true;
    } else if (updater instanceof Assignment) {
      Assignment assignment = (Assignment) updater;
      Expression left = assignment.getLeftHandSide();
      IBinding binding = getBinding(left);
      if (!fIndexBinding.equals(binding)) return false;

      if (Assignment.Operator.PLUS_ASSIGN.equals(assignment.getOperator())) {
        return isOneLiteral(assignment.getRightHandSide());
      } else if (Assignment.Operator.ASSIGN.equals(assignment.getOperator())) {
        Expression right = assignment.getRightHandSide();
        if (!(right instanceof InfixExpression)) return false;

        InfixExpression infixExpression = (InfixExpression) right;
        Expression leftOperand = infixExpression.getLeftOperand();
        IBinding leftBinding = getBinding(leftOperand);
        Expression rightOperand = infixExpression.getRightOperand();
        IBinding rightBinding = getBinding(rightOperand);

        if (fIndexBinding.equals(leftBinding)) {
          return isOneLiteral(rightOperand);
        } else if (fIndexBinding.equals(rightBinding)) {
          return isOneLiteral(leftOperand);
        }
      }
    }
    return false;
  }
  /*
   * Must be one of:
   * <ul>
   * <li>[indexBinding] < [result].length;</li>
   * <li>[result].length > [indexBinding];</li>
   * <li>[indexBinding] < [lengthBinding];</li>
   * <li>[lengthBinding] > [indexBinding];</li>
   * </ul>
   */
  private boolean validateExpression(ForStatement statement) {
    Expression expression = statement.getExpression();
    if (!(expression instanceof InfixExpression)) return false;

    InfixExpression infix = (InfixExpression) expression;

    Expression left = infix.getLeftOperand();
    Expression right = infix.getRightOperand();
    if (left instanceof SimpleName && right instanceof SimpleName) {
      IVariableBinding lengthBinding = fLengthBinding;
      if (lengthBinding == null) return false;

      IBinding leftBinding = ((SimpleName) left).resolveBinding();
      IBinding righBinding = ((SimpleName) right).resolveBinding();

      if (fIndexBinding.equals(leftBinding)) {
        return lengthBinding.equals(righBinding);
      } else if (fIndexBinding.equals(righBinding)) {
        return lengthBinding.equals(leftBinding);
      }

      return false;
    } else if (left instanceof SimpleName) {
      if (!fIndexBinding.equals(((SimpleName) left).resolveBinding())) return false;

      if (!Operator.LESS.equals(infix.getOperator())) return false;

      return validateLengthQuery(right);
    } else if (right instanceof SimpleName) {
      if (!fIndexBinding.equals(((SimpleName) right).resolveBinding())) return false;

      if (!Operator.GREATER.equals(infix.getOperator())) return false;

      return validateLengthQuery(left);
    }

    return false;
  }