/*
   * For all type bindings that have hierarchy problems, artificially fix their superclass/superInterfaces so that the connection
   * can be made.
   */
  private void fixSupertypeBindings() {
    for (int current = this.typeIndex; current >= 0; current--) {
      ReferenceBinding typeBinding = this.typeBindings[current];
      if ((typeBinding.tagBits & TagBits.HierarchyHasProblems) == 0) continue;

      if (typeBinding instanceof SourceTypeBinding) {
        if (typeBinding instanceof LocalTypeBinding) {
          LocalTypeBinding localTypeBinding = (LocalTypeBinding) typeBinding;
          QualifiedAllocationExpression allocationExpression =
              localTypeBinding.scope.referenceContext.allocation;
          TypeReference type;
          if (allocationExpression != null
              && (type = allocationExpression.type) != null
              && type.resolvedType != null) {
            localTypeBinding.setSuperClass((ReferenceBinding) type.resolvedType);
            continue;
          }
        }
        ClassScope scope = ((SourceTypeBinding) typeBinding).scope;
        if (scope != null) {
          TypeDeclaration typeDeclaration = scope.referenceContext;
          TypeReference superclassRef = typeDeclaration == null ? null : typeDeclaration.superclass;
          TypeBinding superclass = superclassRef == null ? null : superclassRef.resolvedType;
          if (superclass != null) {
            superclass = superclass.closestMatch();
          }
          if (superclass instanceof ReferenceBinding) {
            // ensure we are not creating a cycle (see
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=215681 )
            if (!(subTypeOfType((ReferenceBinding) superclass, typeBinding))) {
              ((SourceTypeBinding) typeBinding).setSuperClass((ReferenceBinding) superclass);
            }
          }

          TypeReference[] superInterfaces =
              typeDeclaration == null ? null : typeDeclaration.superInterfaces;
          int length;
          ReferenceBinding[] interfaceBindings = typeBinding.superInterfaces();
          if (superInterfaces != null
              && (length = superInterfaces.length)
                  > (interfaceBindings == null
                      ? 0
                      : interfaceBindings
                          .length)) { // check for interfaceBindings being null (see
                                      // https://bugs.eclipse.org/bugs/show_bug.cgi?id=139689)
            interfaceBindings = new ReferenceBinding[length];
            int index = 0;
            for (int i = 0; i < length; i++) {
              TypeBinding superInterface = superInterfaces[i].resolvedType;
              if (superInterface != null) {
                superInterface = superInterface.closestMatch();
              }
              if (superInterface instanceof ReferenceBinding) {
                // ensure we are not creating a cycle (see
                // https://bugs.eclipse.org/bugs/show_bug.cgi?id=215681 )
                if (!(subTypeOfType((ReferenceBinding) superInterface, typeBinding))) {
                  interfaceBindings[index++] = (ReferenceBinding) superInterface;
                }
              }
            }
            if (index < length)
              System.arraycopy(
                  interfaceBindings, 0, interfaceBindings = new ReferenceBinding[index], 0, index);
            ((SourceTypeBinding) typeBinding).setSuperInterfaces(interfaceBindings);
          }
        }
      } else if (typeBinding instanceof BinaryTypeBinding) {
        try {
          typeBinding.superclass();
        } catch (AbortCompilation e) {
          // allow subsequent call to superclass() to succeed so that we don't have to catch
          // AbortCompilation everywhere
          ((BinaryTypeBinding) typeBinding).tagBits &= ~TagBits.HasUnresolvedSuperclass;
          this.builder.hierarchy.missingTypes.add(
              new String(typeBinding.superclass().sourceName()));
          this.hasMissingSuperClass = true;
        }
        try {
          typeBinding.superInterfaces();
        } catch (AbortCompilation e) {
          // allow subsequent call to superInterfaces() to succeed so that we don't have to catch
          // AbortCompilation everywhere
          ((BinaryTypeBinding) typeBinding).tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
        }
      }
    }
  }