private MethodDeclaration findAfter(
      char[] startWith,
      Scope s,
      int from,
      int to,
      int maxLineCount,
      boolean outsideEnclosingBlock,
      char[][] discouragedNames,
      UnresolvedReferenceNameRequestor nameRequestor) {
    this.requestor = nameRequestor;

    // reinitialize completion scanner to be usable as a normal scanner
    this.completionScanner.cursorLocation = 0;

    if (!outsideEnclosingBlock) {
      // compute location of the end of the current block
      this.completionScanner.resetTo(from + 1, to);
      this.completionScanner.jumpOverBlock();

      to = this.completionScanner.startPosition - 1;
    }

    int maxEnd =
        this.completionScanner.getLineEnd(
            Util.getLineNumber(
                    from, this.completionScanner.lineEnds, 0, this.completionScanner.linePtr)
                + maxLineCount);

    int end;
    if (maxEnd < 0) {
      end = to;
    } else {
      end = maxEnd < to ? maxEnd : to;
    }

    this.parser.startRecordingIdentifiers(from, end);

    MethodDeclaration fakeMethod =
        this.parser.parseSomeStatements(
            from,
            end,
            outsideEnclosingBlock ? FAKE_BLOCKS_COUNT : 0,
            s.compilationUnitScope().referenceContext);

    this.parser.stopRecordingIdentifiers();

    if (!this.initPotentialNamesTables(discouragedNames)) return null;

    this.parentsPtr = -1;
    this.parents = new ASTNode[10];

    return fakeMethod;
  }
  private MethodDeclaration findBefore(
      char[] startWith,
      Scope s,
      int from,
      int recordTo,
      int parseTo,
      int maxLineCount,
      char[][] discouragedNames,
      UnresolvedReferenceNameRequestor nameRequestor) {
    this.requestor = nameRequestor;

    // reinitialize completion scanner to be usable as a normal scanner
    this.completionScanner.cursorLocation = 0;

    int minStart =
        this.completionScanner.getLineStart(
            Util.getLineNumber(
                    recordTo, this.completionScanner.lineEnds, 0, this.completionScanner.linePtr)
                - maxLineCount);

    int start;
    int fakeBlocksCount;
    if (minStart <= from) {
      start = from;
      fakeBlocksCount = 0;
    } else {
      start = minStart;
      fakeBlocksCount = FAKE_BLOCKS_COUNT;
    }

    this.parser.startRecordingIdentifiers(start, recordTo);

    MethodDeclaration fakeMethod =
        this.parser.parseSomeStatements(
            start, parseTo, fakeBlocksCount, s.compilationUnitScope().referenceContext);

    this.parser.stopRecordingIdentifiers();

    if (!this.initPotentialNamesTables(discouragedNames)) return null;

    this.parentsPtr = -1;
    this.parents = new ASTNode[10];

    return fakeMethod;
  }
  public void resolve(MethodScope initializationScope) {
    // the two <constant = Constant.NotAConstant> could be regrouped into
    // a single line but it is clearer to have two lines while the reason of their
    // existence is not at all the same. See comment for the second one.

    // --------------------------------------------------------
    if ((this.bits & ASTNode.HasBeenResolved) != 0) return;
    if (this.binding == null || !this.binding.isValidBinding()) return;

    this.bits |= ASTNode.HasBeenResolved;

    // check if field is hiding some variable - issue is that field binding already got inserted in
    // scope
    // thus must lookup separately in super type and outer context
    ClassScope classScope = initializationScope.enclosingClassScope();

    if (classScope != null) {
      checkHiding:
      {
        SourceTypeBinding declaringType = classScope.enclosingSourceType();
        checkHidingSuperField:
        {
          if (declaringType.superclass == null) break checkHidingSuperField;
          Binding existingVariable =
              classScope.findField(
                  declaringType.superclass, this.name, this, false /*do not resolve hidden field*/);
          if (existingVariable == null) break checkHidingSuperField; // keep checking outer scenario
          if (!existingVariable.isValidBinding())
            break checkHidingSuperField; // keep checking outer scenario
          if (existingVariable instanceof FieldBinding) {
            FieldBinding existingField = (FieldBinding) existingVariable;
            if (existingField.original() == this.binding)
              break checkHidingSuperField; // keep checking outer scenario
          }
          // collision with supertype field
          initializationScope.problemReporter().fieldHiding(this, existingVariable);
          break checkHiding; // already found a matching field
        }
        // only corner case is: lookup of outer field through static declaringType, which isn't
        // detected by #getBinding as lookup starts
        // from outer scope. Subsequent static contexts are detected for free.
        Scope outerScope = classScope.parent;
        if (outerScope.kind == Scope.COMPILATION_UNIT_SCOPE) break checkHiding;
        Binding existingVariable =
            outerScope.getBinding(
                this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
        if (existingVariable == null) break checkHiding;
        if (!existingVariable.isValidBinding()) break checkHiding;
        if (existingVariable == this.binding) break checkHiding;
        if (existingVariable instanceof FieldBinding) {
          FieldBinding existingField = (FieldBinding) existingVariable;
          if (existingField.original() == this.binding) break checkHiding;
          if (!existingField.isStatic() && declaringType.isStatic()) break checkHiding;
        }
        // collision with outer field or local variable
        initializationScope.problemReporter().fieldHiding(this, existingVariable);
      }
    }

    if (this.type != null) { // enum constants have no declared type
      this.type.resolvedType = this.binding.type; // update binding for type reference
    }

    FieldBinding previousField = initializationScope.initializedField;
    int previousFieldID = initializationScope.lastVisibleFieldID;
    try {
      initializationScope.initializedField = this.binding;
      initializationScope.lastVisibleFieldID = this.binding.id;

      //		resolveAnnotations(initializationScope, this.annotations, this.binding);
      // the resolution of the initialization hasn't been done
      if (this.initialization != null) {

        TypeBinding fieldType = this.binding.type;
        TypeBinding initializationType;
        this.initialization.setExpectedType(
            fieldType); // needed in case of generic method invocation
        if (this.initialization instanceof ArrayInitializer) {

          if ((initializationType =
                  this.initialization.resolveTypeExpecting(initializationScope, fieldType))
              != null) {
            ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType;
          }
        } else if ((initializationType = this.initialization.resolveType(initializationScope))
            != null) {

          if (fieldType
              != initializationType) // must call before computeConversion() and typeMismatchError()
          initializationScope
                .compilationUnitScope()
                .recordTypeConversion(fieldType, initializationType);
          if (this.initialization.isConstantValueOfTypeAssignableToType(
                  initializationType, fieldType)
              || (fieldType.isBaseType()
                  && BaseTypeBinding.isWidening(fieldType.id, initializationType.id))
              || initializationType.isCompatibleWith(fieldType)) {
          } else if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType)
              || (initializationType.isBaseType() // narrowing then boxing ?
                  && initializationScope.compilerOptions().sourceLevel
                      >= ClassFileConstants.JDK1_5 // autoboxing
                  && !fieldType.isBaseType()
                  && initialization.isConstantValueOfTypeAssignableToType(
                      initializationType,
                      initializationScope.environment().computeBoxingType(fieldType)))) {
          } else {
            initializationScope
                .problemReporter()
                .typeMismatchError(initializationType, fieldType, this);
          }
        }
        // check for assignment with no effect
        if (this.binding == Assignment.getDirectBinding(this.initialization)) {
          initializationScope.problemReporter().assignmentHasNoEffect(this, this.name);
        }
      }
      // Resolve Javadoc comment if one is present
      if (this.javadoc != null) {
        /*
        if (classScope != null) {
        	this.javadoc.resolve(classScope);
        }
        */
        this.javadoc.resolve(initializationScope);
      } else if (this.binding.declaringClass != null
          && !this.binding.declaringClass.isLocalType()) {
        initializationScope
            .problemReporter()
            .javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers);
      }
    } finally {
      initializationScope.initializedField = previousField;
      initializationScope.lastVisibleFieldID = previousFieldID;
    }
  }