/**
  * Checks additional bindings (methods or types) imported from a single static import. Method is
  * tried first, followed by type. If found, records them. If in the process, import is flagged as
  * duplicate, -1 is returned.
  *
  * @param compoundName
  * @param typesBySimpleNames
  * @param mask
  * @param importReference
  */
 private void checkMoreStaticBindings(
     char[][] compoundName,
     HashtableOfType typesBySimpleNames,
     int mask,
     ImportReference importReference) {
   Binding importBinding = findSingleStaticImport(compoundName, mask);
   if (!importBinding.isValidBinding()) {
     // only continue if the same kind's ambiguous binding is returned
     // may have found an ambiguous type when looking for field or method. Don't continue in that
     // case
     if (importBinding.problemId() == ProblemReasons.Ambiguous) {
       // keep it unless a duplicate can be found below
       checkAndRecordImportBinding(
           importBinding, typesBySimpleNames, importReference, compoundName);
     }
   } else {
     checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName);
   }
   if (((mask & Binding.METHOD) != 0) && (importBinding.kind() == Binding.METHOD)) {
     // found method
     // type is left to be looked for
     // reset METHOD bit to enable lookup for only type
     mask &= ~Binding.METHOD;
     // now search for a type binding
     checkMoreStaticBindings(compoundName, typesBySimpleNames, mask, importReference);
   }
 }
  void faultInImports() {
    boolean unresolvedFound = false;
    // should report unresolved only if we are not suppressing caching of failed resolutions
    boolean reportUnresolved = !this.suppressImportErrors;

    if (this.typeOrPackageCache != null && !this.skipCachingImports)
      return; // can be called when a field constant is resolved before static imports
    if (this.referenceContext.imports == null) {
      this.typeOrPackageCache = new HashtableOfObject(1);
      return;
    }

    // collect the top level type names if a single type import exists
    int numberOfStatements = this.referenceContext.imports.length;
    HashtableOfType typesBySimpleNames = null;
    for (int i = 0; i < numberOfStatements; i++) {
      if ((this.referenceContext.imports[i].bits & ASTNode.OnDemand) == 0) {
        typesBySimpleNames = new HashtableOfType(this.topLevelTypes.length + numberOfStatements);
        for (int j = 0, length = this.topLevelTypes.length; j < length; j++)
          typesBySimpleNames.put(this.topLevelTypes[j].sourceName, this.topLevelTypes[j]);
        break;
      }
    }

    // allocate the import array, add java.lang.* by default
    int numberOfImports = numberOfStatements + 1;
    for (int i = 0; i < numberOfStatements; i++) {
      ImportReference importReference = this.referenceContext.imports[i];
      if (((importReference.bits & ASTNode.OnDemand) != 0)
          && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens)
          && !importReference.isStatic()) {
        numberOfImports--;
        break;
      }
    }
    this.tempImports = new ImportBinding[numberOfImports];
    this.tempImports[0] = getDefaultImports()[0];
    this.importPtr = 1;

    // keep static imports with normal imports until there is a reason to split them up
    // on demand imports continue to be packages & types. need to check on demand type imports for
    // fields/methods
    // single imports change from being just types to types or fields
    nextImport:
    for (int i = 0; i < numberOfStatements; i++) {
      ImportReference importReference = this.referenceContext.imports[i];
      char[][] compoundName = importReference.tokens;

      // skip duplicates or imports of the current package
      for (int j = 0; j < this.importPtr; j++) {
        ImportBinding resolved = this.tempImports[j];
        if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0)
            && resolved.isStatic() == importReference.isStatic()) {
          if (CharOperation.equals(compoundName, resolved.compoundName)) {
            problemReporter().unusedImport(importReference); // since skipped, must be reported now
            continue nextImport;
          }
        }
      }
      if ((importReference.bits & ASTNode.OnDemand) != 0) {
        if (CharOperation.equals(compoundName, this.currentPackageName)) {
          problemReporter().unusedImport(importReference); // since skipped, must be reported now
          continue nextImport;
        }

        Binding importBinding = findImport(compoundName, compoundName.length);
        if (!importBinding.isValidBinding()) {
          problemReporter().importProblem(importReference, importBinding);
          continue nextImport;
        }
        if (importReference.isStatic() && importBinding instanceof PackageBinding) {
          problemReporter().cannotImportPackage(importReference);
          continue nextImport;
        }
        recordImportBinding(new ImportBinding(compoundName, true, importBinding, importReference));
      } else {
        Binding importBinding =
            findSingleImport(
                compoundName,
                Binding.TYPE | Binding.FIELD | Binding.METHOD,
                importReference.isStatic());
        if (!importBinding.isValidBinding()) {
          if (importBinding.problemId() == ProblemReasons.Ambiguous) {
            // keep it unless a duplicate can be found below
          } else {
            unresolvedFound = true;
            if (reportUnresolved) {
              problemReporter().importProblem(importReference, importBinding);
            }
            continue nextImport;
          }
        }
        if (importBinding instanceof PackageBinding) {
          problemReporter().cannotImportPackage(importReference);
          continue nextImport;
        }
        // all the code here which checks for valid bindings have been moved to the method
        // checkAndRecordImportBinding() since bug 361327
        if (checkAndRecordImportBinding(
                importBinding, typesBySimpleNames, importReference, compoundName)
            == -1) continue nextImport;
        if (importReference.isStatic()) {
          // look for more static bindings being imported by single static import(bug 361327).
          // findSingleImport() finds fields first, followed by method and then type
          // So if a type is found, no fields and methods are available anyway
          // similarly when method is found, type may be available but no field available for sure
          if (importBinding.kind() == Binding.FIELD) {
            checkMoreStaticBindings(
                compoundName, typesBySimpleNames, Binding.TYPE | Binding.METHOD, importReference);
          } else if (importBinding.kind() == Binding.METHOD) {
            checkMoreStaticBindings(
                compoundName, typesBySimpleNames, Binding.TYPE, importReference);
          }
        }
      }
    }

    // shrink resolvedImports... only happens if an error was reported
    if (this.tempImports.length > this.importPtr)
      System.arraycopy(
          this.tempImports,
          0,
          this.tempImports = new ImportBinding[this.importPtr],
          0,
          this.importPtr);
    this.imports = this.tempImports;
    int length = this.imports.length;
    this.typeOrPackageCache = new HashtableOfObject(length);
    for (int i = 0; i < length; i++) {
      ImportBinding binding = this.imports[i];
      if (!binding.onDemand && binding.resolvedImport instanceof ReferenceBinding
          || binding instanceof ImportConflictBinding)
        this.typeOrPackageCache.put(binding.compoundName[binding.compoundName.length - 1], binding);
    }
    this.skipCachingImports = this.suppressImportErrors && unresolvedFound;
  }