/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import com.google.gwt.dev.util.collect.HashMap;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.jdt.internal.compiler.util.Util;

import java.util.Hashtable;
import java.util.Iterator;

public class SourceTypeBinding extends ReferenceBinding {
  public ReferenceBinding superclass;
  public ReferenceBinding[] superInterfaces;
  private FieldBinding[] fields;
  private MethodBinding[] methods;
  public ReferenceBinding[] memberTypes;
  public TypeVariableBinding[] typeVariables;

  public ClassScope scope;

  // Synthetics are separated into 5 categories: methods, super methods, fields, class literals, changed declaring type bindings and bridge methods
  // if a new category is added, also increment MAX_SYNTHETICS
  private final static int METHOD_EMUL = 0;
  private final static int FIELD_EMUL = 1;
  private final static int CLASS_LITERAL_EMUL = 2;
  private final static int RECEIVER_TYPE_EMUL = 3;
  
  private final static int MAX_SYNTHETICS = 4;

  HashMap[] synthetics;
  char[] genericReferenceTypeSignature;

  private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder

public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) {
  this.compoundName = compoundName;
  this.fPackage = fPackage;
  this.fileName = scope.referenceCompilationUnit().getFileName();
  this.modifiers = scope.referenceContext.modifiers;
  this.sourceName = scope.referenceContext.name;
  this.scope = scope;

  // expect the fields & methods to be initialized correctly later
  this.fields = Binding.UNINITIALIZED_FIELDS;
  this.methods = Binding.UNINITIALIZED_METHODS;

  computeId();
}

private void addDefaultAbstractMethods() {
  if ((this.tagBits & TagBits.KnowsDefaultAbstractMethods) != 0) return;

  this.tagBits |= TagBits.KnowsDefaultAbstractMethods;
  if (isClass() && isAbstract()) {
    if (this.scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_2)
      return; // no longer added for post 1.2 targets

    ReferenceBinding[] itsInterfaces = superInterfaces();
    if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
      MethodBinding[] defaultAbstracts = null;
      int defaultAbstractsCount = 0;
      ReferenceBinding[] interfacesToVisit = itsInterfaces;
      int nextPosition = interfacesToVisit.length;
      for (int i = 0; i < nextPosition; i++) {
        ReferenceBinding superType = interfacesToVisit[i];
        if (superType.isValidBinding()) {
          MethodBinding[] superMethods = superType.methods();
          nextAbstractMethod: for (int m = superMethods.length; --m >= 0;) {
            MethodBinding method = superMethods[m];
            // explicitly implemented ?
            if (implementsMethod(method))
              continue nextAbstractMethod;
            if (defaultAbstractsCount == 0) {
              defaultAbstracts = new MethodBinding[5];
            } else {
              // already added as default abstract ?
              for (int k = 0; k < defaultAbstractsCount; k++) {
                MethodBinding alreadyAdded = defaultAbstracts[k];
                if (CharOperation.equals(alreadyAdded.selector, method.selector) && alreadyAdded.areParametersEqual(method))
                  continue nextAbstractMethod;
              }
            }
            MethodBinding defaultAbstract = new MethodBinding(
                method.modifiers | ExtraCompilerModifiers.AccDefaultAbstract | ClassFileConstants.AccSynthetic,
                method.selector,
                method.returnType,
                method.parameters,
                method.thrownExceptions,
                this);
            if (defaultAbstractsCount == defaultAbstracts.length)
              System.arraycopy(defaultAbstracts, 0, defaultAbstracts = new MethodBinding[2 * defaultAbstractsCount], 0, defaultAbstractsCount);
            defaultAbstracts[defaultAbstractsCount++] = defaultAbstract;
          }

          if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
            int itsLength = itsInterfaces.length;
            if (nextPosition + itsLength >= interfacesToVisit.length)
              System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
            nextInterface : for (int a = 0; a < itsLength; a++) {
              ReferenceBinding next = itsInterfaces[a];
              for (int b = 0; b < nextPosition; b++)
                if (next == interfacesToVisit[b]) continue nextInterface;
              interfacesToVisit[nextPosition++] = next;
            }
          }
        }
      }
      if (defaultAbstractsCount > 0) {
        int length = this.methods.length;
        System.arraycopy(this.methods, 0, this.methods = new MethodBinding[length + defaultAbstractsCount], 0, length);
        System.arraycopy(defaultAbstracts, 0, this.methods, length, defaultAbstractsCount);
        // re-sort methods
        length = length + defaultAbstractsCount;
        if (length > 1)
          ReferenceBinding.sortMethods(this.methods, 0, length);
        // this.tagBits |= TagBits.AreMethodsSorted; -- already set in #methods()
      }
    }
  }
}
/* Add a new synthetic field for <actualOuterLocalVariable>.
* Answer the new field or the existing field if one already existed.
*/
public FieldBinding addSyntheticFieldForInnerclass(LocalVariableBinding actualOuterLocalVariable) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
    this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();
  
  FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable);
  if (synthField == null) {
    synthField = new SyntheticFieldBinding(
      CharOperation.concat(TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX, actualOuterLocalVariable.name), 
      actualOuterLocalVariable.type, 
      ClassFileConstants.AccPrivate | ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic, 
      this, 
      Constant.NotAConstant,
      this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
    this.synthetics[SourceTypeBinding.FIELD_EMUL].put(actualOuterLocalVariable, synthField);
  }

  // ensure there is not already such a field defined by the user
  boolean needRecheck;
  int index = 1;
  do {
    needRecheck = false;
    FieldBinding existingField;
    if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
      TypeDeclaration typeDecl = this.scope.referenceContext;
      for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
        FieldDeclaration fieldDecl = typeDecl.fields[i];
        if (fieldDecl.binding == existingField) {
          synthField.name = CharOperation.concat(
            TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX,
            actualOuterLocalVariable.name,
            ("$" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
          needRecheck = true;
          break;
        }
      }
    }
  } while (needRecheck);
  return synthField;
}
/* Add a new synthetic field for <enclosingType>.
* Answer the new field or the existing field if one already existed.
*/
public FieldBinding addSyntheticFieldForInnerclass(ReferenceBinding enclosingType) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
    this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();

  FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(enclosingType);
  if (synthField == null) {
    synthField = new SyntheticFieldBinding(
      CharOperation.concat(
        TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
        String.valueOf(enclosingType.depth()).toCharArray()),
      enclosingType,
      ClassFileConstants.AccDefault | ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic,
      this,
      Constant.NotAConstant,
      this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
    this.synthetics[SourceTypeBinding.FIELD_EMUL].put(enclosingType, synthField);
  }
  // ensure there is not already such a field defined by the user
  boolean needRecheck;
  do {
    needRecheck = false;
    FieldBinding existingField;
    if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
      TypeDeclaration typeDecl = this.scope.referenceContext;
      for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
        FieldDeclaration fieldDecl = typeDecl.fields[i];
        if (fieldDecl.binding == existingField) {
          if (this.scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) {
            synthField.name = CharOperation.concat(
              synthField.name,
              "$".toCharArray()); //$NON-NLS-1$
            needRecheck = true;
          } else {
            this.scope.problemReporter().duplicateFieldInType(this, fieldDecl);
          }
          break;
        }
      }
    }
  } while (needRecheck);
  return synthField;
}
/* Add a new synthetic field for a class literal access.
* Answer the new field or the existing field if one already existed.
*/
public FieldBinding addSyntheticFieldForClassLiteral(TypeBinding targetType, BlockScope blockScope) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null)
    this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] = new HashMap();

  // use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class.
  FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].get(targetType);
  if (synthField == null) {
    synthField = new SyntheticFieldBinding(
      CharOperation.concat(
        TypeConstants.SYNTHETIC_CLASS,
        String.valueOf(this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size()).toCharArray()),
      blockScope.getJavaLangClass(),
      ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic,
      this,
      Constant.NotAConstant,
      this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size());
    this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].put(targetType, synthField);
  }
  // ensure there is not already such a field defined by the user
  FieldBinding existingField;
  if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
    TypeDeclaration typeDecl = blockScope.referenceType();
    for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
      FieldDeclaration fieldDecl = typeDecl.fields[i];
      if (fieldDecl.binding == existingField) {
        blockScope.problemReporter().duplicateFieldInType(this, fieldDecl);
        break;
      }
    }
  }   
  return synthField;
}
/* Add a new synthetic field for the emulation of the assert statement.
* Answer the new field or the existing field if one already existed.
*/
public FieldBinding addSyntheticFieldForAssert(BlockScope blockScope) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
    this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();

  FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get("assertionEmulation"); //$NON-NLS-1$
  if (synthField == null) {
    synthField = new SyntheticFieldBinding(
      TypeConstants.SYNTHETIC_ASSERT_DISABLED,
      TypeBinding.BOOLEAN,
      ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal,
      this,
      Constant.NotAConstant,
      this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
    this.synthetics[SourceTypeBinding.FIELD_EMUL].put("assertionEmulation", synthField); //$NON-NLS-1$
  }
  // ensure there is not already such a field defined by the user
  // ensure there is not already such a field defined by the user
  boolean needRecheck;
  int index = 0;
  do {
    needRecheck = false;
    FieldBinding existingField;
    if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
      TypeDeclaration typeDecl = this.scope.referenceContext;
      for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
        FieldDeclaration fieldDecl = typeDecl.fields[i];
        if (fieldDecl.binding == existingField) {
          synthField.name = CharOperation.concat(
            TypeConstants.SYNTHETIC_ASSERT_DISABLED,
            ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
          needRecheck = true;
          break;
        }
      }
    }
  } while (needRecheck);
  return synthField;
}
/* Add a new synthetic field for recording all enum constant values
* Answer the new field or the existing field if one already existed.
*/
public FieldBinding addSyntheticFieldForEnumValues() {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
    this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();

  FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get("enumConstantValues"); //$NON-NLS-1$
  if (synthField == null) {
    synthField = new SyntheticFieldBinding(
      TypeConstants.SYNTHETIC_ENUM_VALUES,
      this.scope.createArrayType(this,1),
      ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal,
      this,
      Constant.NotAConstant,
      this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
    this.synthetics[SourceTypeBinding.FIELD_EMUL].put("enumConstantValues", synthField); //$NON-NLS-1$
  }
  // ensure there is not already such a field defined by the user
  // ensure there is not already such a field defined by the user
  boolean needRecheck;
  int index = 0;
  do {
    needRecheck = false;
    FieldBinding existingField;
    if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
      TypeDeclaration typeDecl = this.scope.referenceContext;
      for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
        FieldDeclaration fieldDecl = typeDecl.fields[i];
        if (fieldDecl.binding == existingField) {
          synthField.name = CharOperation.concat(
            TypeConstants.SYNTHETIC_ENUM_VALUES,
            ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
          needRecheck = true;
          break;
        }
      }
    }
  } while (needRecheck);
  return synthField;
}
/* Add a new synthetic access method for read/write access to <targetField>.
  Answer the new method or the existing method if one already existed.
*/
public SyntheticMethodBinding addSyntheticMethod(FieldBinding targetField, boolean isReadAccess) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
    this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();

  SyntheticMethodBinding accessMethod = null;
  SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetField);
  if (accessors == null) {
    accessMethod = new SyntheticMethodBinding(targetField, isReadAccess, this);
    this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetField, accessors = new SyntheticMethodBinding[2]);
    accessors[isReadAccess ? 0 : 1] = accessMethod;   
  } else {
    if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) {
      accessMethod = new SyntheticMethodBinding(targetField, isReadAccess, this);
      accessors[isReadAccess ? 0 : 1] = accessMethod;
    }
  }
  return accessMethod;
}
/* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
 * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
*/
public SyntheticMethodBinding addSyntheticEnumMethod(char[] selector) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
    this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();

  SyntheticMethodBinding accessMethod = null;
  SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(selector);
  if (accessors == null) {
    accessMethod = new SyntheticMethodBinding(this, selector);
    this.synthetics[SourceTypeBinding.METHOD_EMUL].put(selector, accessors = new SyntheticMethodBinding[2]);
    accessors[0] = accessMethod;    
  } else {
    if ((accessMethod = accessors[0]) == null) {
      accessMethod = new SyntheticMethodBinding(this, selector);
      accessors[0] = accessMethod;
    }
  }
  return accessMethod;
}
/*
 * Add a synthetic field to handle the cache of the switch translation table for the corresponding enum type 
 */
public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(char[] fieldName, String key) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
    this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();

  SyntheticFieldBinding synthField = (SyntheticFieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(key);
  if (synthField == null) {
    synthField = new SyntheticFieldBinding(
      fieldName,
      this.scope.createArrayType(TypeBinding.INT,1),
      ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic,
      this,
      Constant.NotAConstant,
      this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
    this.synthetics[SourceTypeBinding.FIELD_EMUL].put(key, synthField);
  }
  // ensure there is not already such a field defined by the user
  boolean needRecheck;
  int index = 0;
  do {
    needRecheck = false;
    FieldBinding existingField;
    if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
      TypeDeclaration typeDecl = this.scope.referenceContext;
      for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
        FieldDeclaration fieldDecl = typeDecl.fields[i];
        if (fieldDecl.binding == existingField) {
          synthField.name = CharOperation.concat(
            fieldName,
            ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
          needRecheck = true;
          break;
        }
      }
    }
  } while (needRecheck);
  return synthField;
}
/* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
 * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
*/
public SyntheticMethodBinding addSyntheticMethodForSwitchEnum(TypeBinding enumBinding) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
    this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();

  SyntheticMethodBinding accessMethod = null;
  char[] selector = CharOperation.concat(TypeConstants.SYNTHETIC_SWITCH_ENUM_TABLE, enumBinding.constantPoolName());
  CharOperation.replace(selector, '/', '$');
  final String key = new String(selector);
  SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(key);
  // first add the corresponding synthetic field
  if (accessors == null) {
    // then create the synthetic method
    final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key);
    accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
    this.synthetics[SourceTypeBinding.METHOD_EMUL].put(key, accessors = new SyntheticMethodBinding[2]);
    accessors[0] = accessMethod;
  } else {
    if ((accessMethod = accessors[0]) == null) {
      final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key);
      accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
      accessors[0] = accessMethod;
    }
  }
  return accessMethod;
}
/* Add a new synthetic access method for access to <targetMethod>.
 * Must distinguish access method used for super access from others (need to use invokespecial bytecode)
  Answer the new method or the existing method if one already existed.
*/
public SyntheticMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
    this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();

  SyntheticMethodBinding accessMethod = null;
  SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetMethod);
  if (accessors == null) {
    accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess, this);
    this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetMethod, accessors = new SyntheticMethodBinding[2]);
    accessors[isSuperAccess ? 0 : 1] = accessMethod;    
  } else {
    if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) {
      accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess, this);
      accessors[isSuperAccess ? 0 : 1] = accessMethod;
    }
  }
  return accessMethod;
}
/* 
 * Record the fact that bridge methods need to be generated to override certain inherited methods
 */
public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge, MethodBinding targetMethod) {
  if (isInterface()) return null; // only classes & enums get bridge methods
  // targetMethod may be inherited
  if (inheritedMethodToBridge.returnType.erasure() == targetMethod.returnType.erasure()
    && inheritedMethodToBridge.areParameterErasuresEqual(targetMethod)) {
      return null; // do not need bridge method
  }
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) {
    this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();
  } else {
    // check to see if there is another equivalent inheritedMethod already added
    Iterator synthMethods = this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator();
    while (synthMethods.hasNext()) {
      Object synthetic = synthMethods.next();
      if (synthetic instanceof MethodBinding) {
        MethodBinding method = (MethodBinding) synthetic;
        if (CharOperation.equals(inheritedMethodToBridge.selector, method.selector)
          && inheritedMethodToBridge.returnType.erasure() == method.returnType.erasure()
          && inheritedMethodToBridge.areParameterErasuresEqual(method)) {
            return null;
        }
      }
    }
  }

  SyntheticMethodBinding accessMethod = null;
  SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge);
  if (accessors == null) {
    accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this);
    this.synthetics[SourceTypeBinding.METHOD_EMUL].put(inheritedMethodToBridge, accessors = new SyntheticMethodBinding[2]);
    accessors[1] = accessMethod;    
  } else {
    if ((accessMethod = accessors[1]) == null) {
      accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this);
      accessors[1] = accessMethod;
    }
  }
  return accessMethod;
}
boolean areFieldsInitialized() {
  return this.fields != Binding.UNINITIALIZED_FIELDS;
}
boolean areMethodsInitialized() {
  return this.methods != Binding.UNINITIALIZED_METHODS;
}
public int kind() {
  if (this.typeVariables != Binding.NO_TYPE_VARIABLES) return Binding.GENERIC_TYPE;
  return Binding.TYPE;
}

public char[] computeUniqueKey(boolean isLeaf) {
  char[] uniqueKey = super.computeUniqueKey(isLeaf);
  if (uniqueKey.length == 2) return uniqueKey; // problem type's unique key is "L;"
  if (Util.isClassFileName(this.fileName)) return uniqueKey; // no need to insert compilation unit name for a .class file
  
  // insert compilation unit name if the type name is not the main type name
  int end = CharOperation.lastIndexOf('.', this.fileName);
  if (end != -1) {
    int start = CharOperation.lastIndexOf('/', this.fileName) + 1;
    char[] mainTypeName = CharOperation.subarray(this.fileName, start, end);
    start = CharOperation.lastIndexOf('/', uniqueKey) + 1;
    if (start == 0)
      start = 1; // start after L
    end = CharOperation.indexOf('$', uniqueKey, start);
    if (end == -1)
      end = CharOperation.indexOf('<', uniqueKey, start);
    if (end == -1)
      end = CharOperation.indexOf(';', uniqueKey, start);
    char[] topLevelType = CharOperation.subarray(uniqueKey, start, end);
    if (!CharOperation.equals(topLevelType, mainTypeName)) {
      StringBuffer buffer = new StringBuffer();
      buffer.append(uniqueKey, 0, start);
      buffer.append(mainTypeName);
      buffer.append('~');
      buffer.append(topLevelType);
      buffer.append(uniqueKey, end, uniqueKey.length - end);
      int length = buffer.length();
      uniqueKey = new char[length];
      buffer.getChars(0, length, uniqueKey, 0);
      return uniqueKey;
    }
  }
  return uniqueKey;
}

void faultInTypesForFieldsAndMethods() {
  // check @Deprecated annotation
  getAnnotationTagBits(); // marks as deprecated by side effect
  ReferenceBinding enclosingType = this.enclosingType();
  if (enclosingType != null && enclosingType.isViewedAsDeprecated() && !this.isDeprecated())
    this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
  fields();
  methods();

  for (int i = 0, length = this.memberTypes.length; i < length; i++)
    ((SourceTypeBinding) this.memberTypes[i]).faultInTypesForFieldsAndMethods();
}
// NOTE: the type of each field of a source type is resolved when needed
public FieldBinding[] fields() {
  if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
    return this.fields; 

  int failed = 0;
  FieldBinding[] resolvedFields = this.fields;
  try {
    // lazily sort fields
    if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
      int length = this.fields.length;
      if (length > 1)
        ReferenceBinding.sortFields(this.fields, 0, length);
      this.tagBits |= TagBits.AreFieldsSorted;
    }
    for (int i = 0, length = this.fields.length; i < length; i++) {
      if (resolveTypeFor(this.fields[i]) == null) {
        // do not alter original field array until resolution is over, due to reentrance (143259)
        if (resolvedFields == this.fields) {
          System.arraycopy(this.fields, 0, resolvedFields = new FieldBinding[length], 0, length);
        }
        resolvedFields[i] = null;
        failed++;
      }
    }
  } finally {
    if (failed > 0) {
      // ensure fields are consistent reqardless of the error
      int newSize = resolvedFields.length - failed;
      if (newSize == 0)
        return this.fields = Binding.NO_FIELDS;

      FieldBinding[] newFields = new FieldBinding[newSize];
      for (int i = 0, j = 0, length = resolvedFields.length; i < length; i++) {
        if (resolvedFields[i] != null)
          newFields[j++] = resolvedFields[i];
      }
      this.fields = newFields;
    }
  }
  this.tagBits |= TagBits.AreFieldsComplete;
  return this.fields;
}
/**
 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
 */
public char[] genericTypeSignature() {
    if (this.genericReferenceTypeSignature == null)
      this.genericReferenceTypeSignature = computeGenericTypeSignature(this.typeVariables);
    return this.genericReferenceTypeSignature;
}
/**
 * <param1 ... paramN>superclass superinterface1 ... superinterfaceN
 * <T:LY<TT;>;U:Ljava/lang/Object;V::Ljava/lang/Runnable;:Ljava/lang/Cloneable;:Ljava/util/Map;>Ljava/lang/Exception;Ljava/lang/Runnable;
 */
public char[] genericSignature() {
    StringBuffer sig = null;
  if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
      sig = new StringBuffer(10);
      sig.append('<');
      for (int i = 0, length = this.typeVariables.length; i < length; i++)
          sig.append(this.typeVariables[i].genericSignature());
      sig.append('>');
  } else {
      // could still need a signature if any of supertypes is parameterized
      noSignature: if (this.superclass == null || !this.superclass.isParameterizedType()) {
        for (int i = 0, length = this.superInterfaces.length; i < length; i++)
            if (this.superInterfaces[i].isParameterizedType())
          break noSignature;
          return null;
      }
      sig = new StringBuffer(10);
  }
  if (this.superclass != null)
    sig.append(this.superclass.genericTypeSignature());
  else // interface scenario only (as Object cannot be generic) - 65953
    sig.append(this.scope.getJavaLangObject().genericTypeSignature());
    for (int i = 0, length = this.superInterfaces.length; i < length; i++)
        sig.append(this.superInterfaces[i].genericTypeSignature());
  return sig.toString().toCharArray();
}

/**
 * Compute the tagbits for standard annotations. For source types, these could require
 * lazily resolving corresponding annotation nodes, in case of forward references.
 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
 */
public long getAnnotationTagBits() {
  if ((this.tagBits & TagBits.AnnotationResolved) == 0 && this.scope != null) {
    TypeDeclaration typeDecl = this.scope.referenceContext;
    boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
    try {
      typeDecl.staticInitializerScope.insideTypeAnnotation = true;
      ASTNode.resolveAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this);
    } finally {
      typeDecl.staticInitializerScope.insideTypeAnnotation = old;
    }
    if ((this.tagBits & TagBits.AnnotationDeprecated) != 0)
      this.modifiers |= ClassFileConstants.AccDeprecated;
  }
  return this.tagBits;
}
public MethodBinding[] getDefaultAbstractMethods() {
  int count = 0;
  for (int i = this.methods.length; --i >= 0;)
    if (this.methods[i].isDefaultAbstract())
      count++;
  if (count == 0) return Binding.NO_METHODS;

  MethodBinding[] result = new MethodBinding[count];
  count = 0;
  for (int i = this.methods.length; --i >= 0;)
    if (this.methods[i].isDefaultAbstract())
      result[count++] = this.methods[i];
  return result;
}
// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
  int argCount = argumentTypes.length;
  if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
    long range;
    if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
      nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
        MethodBinding method = this.methods[imethod];
        if (method.parameters.length == argCount) {
          TypeBinding[] toMatch = method.parameters;
          for (int iarg = 0; iarg < argCount; iarg++)
            if (toMatch[iarg] != argumentTypes[iarg])
              continue nextMethod;
          return method;
        }
      }
    }
  } else {
    // lazily sort methods
    if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
      int length = this.methods.length;
      if (length > 1)
        ReferenceBinding.sortMethods(this.methods, 0, length);
      this.tagBits |= TagBits.AreMethodsSorted;
    }   
    long range;
    if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
      nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
        MethodBinding method = this.methods[imethod];
        if (resolveTypesFor(method) == null || method.returnType == null) {
          methods();
          return getExactConstructor(argumentTypes);  // try again since the problem methods have been removed
        }
        if (method.parameters.length == argCount) {
          TypeBinding[] toMatch = method.parameters;
          for (int iarg = 0; iarg < argCount; iarg++)
            if (toMatch[iarg] != argumentTypes[iarg])
              continue nextMethod;
          return method;
        }
      }
    }
  } 
  return null;
}

//NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
//searches up the hierarchy as long as no potential (but not exact) match was found.
public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
  // sender from refScope calls recordTypeReference(this)
  int argCount = argumentTypes.length;
  boolean foundNothing = true;

  if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
    long range;
    if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
      nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
        MethodBinding method = this.methods[imethod];
        foundNothing = false; // inner type lookups must know that a method with this name exists
        if (method.parameters.length == argCount) {
          TypeBinding[] toMatch = method.parameters;
          for (int iarg = 0; iarg < argCount; iarg++)
            if (toMatch[iarg] != argumentTypes[iarg])
              continue nextMethod;
          return method;
        }
      }
    }
  } else {
    // lazily sort methods
    if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
      int length = this.methods.length;
      if (length > 1)
        ReferenceBinding.sortMethods(this.methods, 0, length);
      this.tagBits |= TagBits.AreMethodsSorted;
    }
    
    long range;
    if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
      // check unresolved method
      int start = (int) range, end = (int) (range >> 32);
      for (int imethod = start; imethod <= end; imethod++) {
        MethodBinding method = this.methods[imethod];     
        if (resolveTypesFor(method) == null || method.returnType == null) {
          methods();
          return getExactMethod(selector, argumentTypes, refScope); // try again since the problem methods have been removed
        }
      }
      // check dup collisions
      boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
      for (int i = start; i <= end; i++) {
        MethodBinding method1 = this.methods[i];
        for (int j = end; j > i; j--) {
          MethodBinding method2 = this.methods[j];
          boolean paramsMatch = isSource15
            ? method1.areParameterErasuresEqual(method2)
            : method1.areParametersEqual(method2);
          if (paramsMatch) {
            methods();
            return getExactMethod(selector, argumentTypes, refScope); // try again since the problem methods have been removed
          }
        }
      }
      nextMethod: for (int imethod = start; imethod <= end; imethod++) {
        MethodBinding method = this.methods[imethod];           
        TypeBinding[] toMatch = method.parameters;
        if (toMatch.length == argCount) {
          for (int iarg = 0; iarg < argCount; iarg++)
            if (toMatch[iarg] != argumentTypes[iarg])
              continue nextMethod;
          return method;
        }
      }       
    }
  }

  if (foundNothing) {
    if (isInterface()) {
       if (this.superInterfaces.length == 1) {
        if (refScope != null)
          refScope.recordTypeReference(this.superInterfaces[0]);
        return this.superInterfaces[0].getExactMethod(selector, argumentTypes, refScope);
       }
    } else if (this.superclass != null) {
      if (refScope != null)
        refScope.recordTypeReference(this.superclass);
      return this.superclass.getExactMethod(selector, argumentTypes, refScope);
    }
  }
  return null;
}

//NOTE: the type of a field of a source type is resolved when needed
public FieldBinding getField(char[] fieldName, boolean needResolve) {
  
  if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
    return ReferenceBinding.binarySearch(fieldName, this.fields);

  // lazily sort fields
  if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
    int length = this.fields.length;
    if (length > 1)
      ReferenceBinding.sortFields(this.fields, 0, length);
    this.tagBits |= TagBits.AreFieldsSorted;
  }   
  // always resolve anyway on source types
  FieldBinding field = ReferenceBinding.binarySearch(fieldName, this.fields);
  if (field != null) {
    FieldBinding result = null;
    try {
      result = resolveTypeFor(field);
      return result;
    } finally {
      if (result == null) {
        // ensure fields are consistent reqardless of the error
        int newSize = this.fields.length - 1;
        if (newSize == 0) {
          this.fields = Binding.NO_FIELDS;
        } else {
          FieldBinding[] newFields = new FieldBinding[newSize];
          int index = 0;
          for (int i = 0, length = this.fields.length; i < length; i++) {
            FieldBinding f = this.fields[i];
            if (f == field) continue;
            newFields[index++] = f;
          }
          this.fields = newFields;
        }
      }
    }
  }
  return null;
}

// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
public MethodBinding[] getMethods(char[] selector) {
  if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
    long range;
    if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
      int start = (int) range, end = (int) (range >> 32);
      int length = end - start + 1;
      MethodBinding[] result;
      System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
      return result;
    } else {
      return Binding.NO_METHODS;      
    }
  }
  // lazily sort methods
  if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
    int length = this.methods.length;
    if (length > 1)
      ReferenceBinding.sortMethods(this.methods, 0, length);
    this.tagBits |= TagBits.AreMethodsSorted;
  }
  MethodBinding[] result; 
  long range;
  if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
    int start = (int) range, end = (int) (range >> 32);
    for (int i = start; i <= end; i++) {
      MethodBinding method = this.methods[i];
      if (resolveTypesFor(method) == null || method.returnType == null) {
        methods();
        return getMethods(selector); // try again since the problem methods have been removed
      }
    }
    int length = end - start + 1;
    System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
  } else {
    return Binding.NO_METHODS;
  }
  boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
  for (int i = 0, length = result.length - 1; i < length; i++) {
    MethodBinding method = result[i];
    for (int j = length; j > i; j--) {
      boolean paramsMatch = isSource15
        ? method.areParameterErasuresEqual(result[j])
        : method.areParametersEqual(result[j]);
      if (paramsMatch) {
        methods();
        return getMethods(selector); // try again since the duplicate methods have been removed
      }
    }
  }
  return result;
}
/* Answer the synthetic field for <actualOuterLocalVariable>
* or null if one does not exist.
*/
public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) {
  if (this.synthetics == null || this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null;
  return (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable);
}
/* Answer the synthetic field for <targetEnclosingType>
* or null if one does not exist.
*/
public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {

  if (this.synthetics == null || this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null;
  FieldBinding field = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(targetEnclosingType);
  if (field != null) return field;

  // type compatibility : to handle cases such as
  // class T { class M{}}
  // class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
  if (!onlyExactMatch){
    Iterator accessFields = this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator();
    while (accessFields.hasNext()) {
      field = (FieldBinding) accessFields.next();
      if (CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, field.name)
        && field.type.findSuperTypeOriginatingFrom(targetEnclosingType) != null)
          return field;
    }
  }
  return null;
}
/* 
 * Answer the bridge method associated for an  inherited methods or null if one does not exist
 */
public SyntheticMethodBinding getSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) {
  if (this.synthetics == null) return null;
  if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) return null;
  SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge);
  if (accessors == null) return null;
  return accessors[1];
}

/**
 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
 */
public void initializeDeprecatedAnnotationTagBits() {
  if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
    TypeDeclaration typeDecl = this.scope.referenceContext;
    boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
    try {
      typeDecl.staticInitializerScope.insideTypeAnnotation = true;
      ASTNode.resolveDeprecatedAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this);
      this.tagBits |= TagBits.DeprecatedAnnotationResolved;
    } finally {
      typeDecl.staticInitializerScope.insideTypeAnnotation = old;
    }
    if ((this.tagBits & TagBits.AnnotationDeprecated) != 0) {
      this.modifiers |= ClassFileConstants.AccDeprecated;
    }
  }
}

// ensure the receiver knows its hierarchy & fields/methods so static imports can be resolved correctly
// see bug 230026
void initializeForStaticImports() {
  if (this.scope == null) return; // already initialized

  if (this.superInterfaces == null)
    this.scope.connectTypeHierarchy();
  this.scope.buildFields();
  this.scope.buildMethods();
}

/**
 * Returns true if a type is identical to another one,
 * or for generic types, true if compared to its raw type.
 */
public boolean isEquivalentTo(TypeBinding otherType) {

  if (this == otherType) return true;
  if (otherType == null) return false;
  switch(otherType.kind()) {

    case Binding.WILDCARD_TYPE :
    case Binding.INTERSECTION_TYPE:
      return ((WildcardBinding) otherType).boundCheck(this);

    case Binding.PARAMETERIZED_TYPE :
      if ((otherType.tagBits & TagBits.HasDirectWildcard) == 0 && (!this.isMemberType() || !otherType.isMemberType())) 
        return false; // should have been identical
      ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
      if (this != otherParamType.genericType()) 
        return false;
      if (!isStatic()) { // static member types do not compare their enclosing
              ReferenceBinding enclosing = enclosingType();
              if (enclosing != null) {
                ReferenceBinding otherEnclosing = otherParamType.enclosingType();
                if (otherEnclosing == null) return false;
                if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
            if (enclosing != otherEnclosing) return false;
                } else {
                  if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
                }
              }       
      }
      int length = this.typeVariables == null ? 0 : this.typeVariables.length;
      TypeBinding[] otherArguments = otherParamType.arguments;
      int otherLength = otherArguments == null ? 0 : otherArguments.length;
      if (otherLength != length) 
        return false;
      for (int i = 0; i < length; i++)
        if (!this.typeVariables[i].isTypeArgumentContainedBy(otherArguments[i]))
          return false;
      return true;

    case Binding.RAW_TYPE :
          return otherType.erasure() == this;
  }
  return false;
}
public boolean isGenericType() {
    return this.typeVariables != Binding.NO_TYPE_VARIABLES;
}
public ReferenceBinding[] memberTypes() {
  return this.memberTypes;
}
public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null)
    this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap();

  Hashtable fieldMap = (Hashtable) this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].get(targetField);
  if (fieldMap == null) {
    fieldMap = new Hashtable(5);
    this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(targetField, fieldMap);
  }
  FieldBinding updatedField = (FieldBinding) fieldMap.get(newDeclaringClass);
  if (updatedField == null){
    updatedField = new FieldBinding(targetField, newDeclaringClass);
    fieldMap.put(newDeclaringClass, updatedField);
  }
  return updatedField;
}
public MethodBinding getUpdatedMethodBinding(MethodBinding targetMethod, ReferenceBinding newDeclaringClass) {
  if (this.synthetics == null)
    this.synthetics = new HashMap[MAX_SYNTHETICS];
  if (this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null)
    this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap();

  Hashtable methodMap = (Hashtable) this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].get(targetMethod);
  if (methodMap == null) {
    methodMap = new Hashtable(5);
    this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(targetMethod, methodMap);
  }
  MethodBinding updatedMethod = (MethodBinding) methodMap.get(newDeclaringClass);
  if (updatedMethod == null){
    updatedMethod = new MethodBinding(targetMethod, newDeclaringClass);
    methodMap.put(newDeclaringClass, updatedMethod);
  }
  return updatedMethod;
}
public boolean hasMemberTypes() {
    return this.memberTypes.length > 0;
}
// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
public MethodBinding[] methods() {
  if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
    return this.methods;
  
  // lazily sort methods
  if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
    int length = this.methods.length;
    if (length > 1)
      ReferenceBinding.sortMethods(this.methods, 0, length);
    this.tagBits |= TagBits.AreMethodsSorted;
  }

  int failed = 0;
  MethodBinding[] resolvedMethods = this.methods;
  try {
    for (int i = 0, length = this.methods.length; i < length; i++) {
      if (resolveTypesFor(this.methods[i]) == null) {
        // do not alter original method array until resolution is over, due to reentrance (143259)
        if (resolvedMethods == this.methods) {
          System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
        }       
        resolvedMethods[i] = null; // unable to resolve parameters
        failed++;
      }
    }

    // find & report collision cases
    boolean complyTo15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
    for (int i = 0, length = this.methods.length; i < length; i++) {
      MethodBinding method = resolvedMethods[i];
      if (method == null) 
        continue;
      char[] selector = method.selector;
      AbstractMethodDeclaration methodDecl = null;
      nextSibling: for (int j = i + 1; j < length; j++) {
        MethodBinding method2 = resolvedMethods[j];
        if (method2 == null)
          continue nextSibling;
        if (!CharOperation.equals(selector, method2.selector)) 
          break nextSibling; // methods with same selector are contiguous

        if (complyTo15 && method.returnType != null && method2.returnType != null) {
          // 8.4.2, for collision to be detected between m1 and m2:
          // signature(m1) == signature(m2) i.e. same arity, same type parameter count, can be substituted
          // signature(m1) == erasure(signature(m2)) or erasure(signature(m1)) == signature(m2)
          TypeBinding[] params1 = method.parameters;
          TypeBinding[] params2 = method2.parameters;
          int pLength = params1.length;
          if (pLength != params2.length)
            continue nextSibling;

          TypeVariableBinding[] vars = method.typeVariables;
          TypeVariableBinding[] vars2 = method2.typeVariables;
          boolean equalTypeVars = vars == vars2;
          MethodBinding subMethod = method2;
          if (!equalTypeVars) {
            MethodBinding temp = method.computeSubstitutedMethod(method2, this.scope.environment());
            if (temp != null) {
              equalTypeVars = true;
              subMethod = temp;
            }
          }
          boolean equalParams = method.areParametersEqual(subMethod);
          if (equalParams && equalTypeVars) {
            // duplicates regardless of return types
          } else if (method.returnType.erasure() == subMethod.returnType.erasure() && (equalParams || method.areParameterErasuresEqual(method2))) {
            // name clash for sure if not duplicates, report as duplicates
          } else if (!equalTypeVars && vars != Binding.NO_TYPE_VARIABLES && vars2 != Binding.NO_TYPE_VARIABLES) {
            // type variables are different so we can distinguish between methods
            continue nextSibling;
          } else if (pLength > 0) {
            // check to see if the erasure of either method is equal to the other
            int index = pLength;
            for (; --index >= 0;) {
              if (params1[index] != params2[index].erasure())
                break;
              if (params1[index] == params2[index]) {
                TypeBinding type = params1[index].leafComponentType();
                if (type instanceof SourceTypeBinding && type.typeVariables() != Binding.NO_TYPE_VARIABLES) {
                  index = pLength; // handle comparing identical source types like X<T>... its erasure is itself BUT we need to answer false
                  break;
                }
              }
            }
            if (index >= 0 && index < pLength) {
              for (index = pLength; --index >= 0;)
                if (params1[index].erasure() != params2[index])
                  break;
            }
            if (index >= 0)
              continue nextSibling;
          }
        } else if (!method.areParametersEqual(method2)) { // prior to 1.5, parameter identity meant a collision case
          continue nextSibling;
        }
        boolean isEnumSpecialMethod = isEnum() && (CharOperation.equals(selector,TypeConstants.VALUEOF) || CharOperation.equals(selector,TypeConstants.VALUES));
        // report duplicate
        if (methodDecl == null) {
          methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost & may still be null if method is special
          if (methodDecl != null && methodDecl.binding != null) { // ensure its a valid user defined method
            if (isEnumSpecialMethod) {
              this.scope.problemReporter().duplicateEnumSpecialMethod(this, methodDecl);
            } else {
              this.scope.problemReporter().duplicateMethodInType(this, methodDecl, method.areParametersEqual(method2));
            }
            methodDecl.binding = null;
            // do not alter original method array until resolution is over, due to reentrance (143259)
            if (resolvedMethods == this.methods) {
              System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
            }               
            resolvedMethods[i] = null;
            failed++;
          }
        }
        AbstractMethodDeclaration method2Decl = method2.sourceMethod();
        if (method2Decl != null && method2Decl.binding != null) { // ensure its a valid user defined method
          if (isEnumSpecialMethod) {
            this.scope.problemReporter().duplicateEnumSpecialMethod(this, method2Decl);
          } else {
            this.scope.problemReporter().duplicateMethodInType(this, method2Decl, method.areParametersEqual(method2));
          }
          method2Decl.binding = null;
          // do not alter original method array until resolution is over, due to reentrance (143259)
          if (resolvedMethods == this.methods) {
            System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
          }             
          resolvedMethods[j] = null;
          failed++;
        }
      }
      if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
        methodDecl = method.sourceMethod();
        if (methodDecl != null) {
          methodDecl.binding = null;
        }
        // do not alter original method array until resolution is over, due to reentrance (143259)
        if (resolvedMethods == this.methods) {
          System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
        }           
        resolvedMethods[i] = null;
        failed++;
      }
    }
  } finally {
    if (failed > 0) {
      int newSize = resolvedMethods.length - failed;
      if (newSize == 0) {
        this.methods = Binding.NO_METHODS;
      } else {
        MethodBinding[] newMethods = new MethodBinding[newSize];
        for (int i = 0, j = 0, length = resolvedMethods.length; i < length; i++)
          if (resolvedMethods[i] != null)
            newMethods[j++] = resolvedMethods[i];
        this.methods = newMethods;
      }
    }

    // handle forward references to potential default abstract methods
    addDefaultAbstractMethods();
    this.tagBits |= TagBits.AreMethodsComplete;
  }   
  return this.methods;
}
private FieldBinding resolveTypeFor(FieldBinding field) {
  if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
    return field;

  if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
    if ((field.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
      field.modifiers |= ClassFileConstants.AccDeprecated;
  }
  if (isViewedAsDeprecated() && !field.isDeprecated())
    field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;  
  if (hasRestrictedAccess())
    field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
  FieldDeclaration[] fieldDecls = this.scope.referenceContext.fields;
  for (int f = 0, length = fieldDecls.length; f < length; f++) {
    if (fieldDecls[f].binding != field)
      continue;

      MethodScope initializationScope = field.isStatic() 
        ? this.scope.referenceContext.staticInitializerScope 
        : this.scope.referenceContext.initializerScope;
      FieldBinding previousField = initializationScope.initializedField;
      try {
        initializationScope.initializedField = field;
        FieldDeclaration fieldDecl = fieldDecls[f];
        TypeBinding fieldType = 
          fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT
            ? initializationScope.environment().convertToRawType(this, false /*do not force conversion of enclosing types*/) // enum constant is implicitly of declaring enum type
            : fieldDecl.type.resolveType(initializationScope, true /* check bounds*/);
        field.type = fieldType;
        field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
        if (fieldType == null) {
          fieldDecl.binding = null;
          return null;
        }
        if (fieldType == TypeBinding.VOID) {
          this.scope.problemReporter().variableTypeCannotBeVoid(fieldDecl);
          fieldDecl.binding = null;
          return null;
        }
        if (fieldType.isArrayType() && ((ArrayBinding) fieldType).leafComponentType == TypeBinding.VOID) {
          this.scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecl);
          fieldDecl.binding = null;
          return null;
        }
        if ((fieldType.tagBits & TagBits.HasMissingType) != 0) {
          field.tagBits |= TagBits.HasMissingType;
        }           
        TypeBinding leafType = fieldType.leafComponentType();
        if (leafType instanceof ReferenceBinding && (((ReferenceBinding)leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
          field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
        }       
      } finally {
          initializationScope.initializedField = previousField;
      }
    return field;
  }
  return null; // should never reach this point
}
public MethodBinding resolveTypesFor(MethodBinding method) {
  if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
    return method;

  if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
    if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
      method.modifiers |= ClassFileConstants.AccDeprecated;
  }
  if (isViewedAsDeprecated() && !method.isDeprecated())
    method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
  if (hasRestrictedAccess())
    method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;

  AbstractMethodDeclaration methodDecl = method.sourceMethod();
  if (methodDecl == null) return null; // method could not be resolved in previous iteration

  TypeParameter[] typeParameters = methodDecl.typeParameters();
  if (typeParameters != null) {
    methodDecl.scope.connectTypeVariables(typeParameters, true);
    // Perform deferred bound checks for type variables (only done after type variable hierarchy is connected)
    for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++)
      typeParameters[i].checkBounds(methodDecl.scope);
  }
  TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
  if (exceptionTypes != null) {
    int size = exceptionTypes.length;
    method.thrownExceptions = new ReferenceBinding[size];
    int count = 0;
    ReferenceBinding resolvedExceptionType;
    for (int i = 0; i < size; i++) {
      resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope, true /* check bounds*/);
      if (resolvedExceptionType == null)
        continue;
      if (resolvedExceptionType.isBoundParameterizedType()) {
        methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType, exceptionTypes[i]);
        continue;
      }
      if (resolvedExceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
        if (resolvedExceptionType.isValidBinding()) {
          methodDecl.scope.problemReporter().cannotThrowType(exceptionTypes[i], resolvedExceptionType);
          continue;
        }
      }
      if ((resolvedExceptionType.tagBits & TagBits.HasMissingType) != 0) {
        method.tagBits |= TagBits.HasMissingType;
      }           
      method.modifiers |= (resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature);
      method.thrownExceptions[count++] = resolvedExceptionType;
    }
    if (count < size)
      System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count);
  }

  boolean foundArgProblem = false;
  Argument[] arguments = methodDecl.arguments;
  if (arguments != null) {
    int size = arguments.length;
    method.parameters = Binding.NO_PARAMETERS;
    TypeBinding[] newParameters = new TypeBinding[size];
    for (int i = 0; i < size; i++) {
      Argument arg = arguments[i];
      if (arg.annotations != null) {
        method.tagBits |= TagBits.HasParameterAnnotations;
      }
      TypeBinding parameterType = arg.type.resolveType(methodDecl.scope, true /* check bounds*/);
      if (parameterType == null) {
        foundArgProblem = true;
      } else if (parameterType == TypeBinding.VOID) {
        methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg);
        foundArgProblem = true;
      } else {
        if ((parameterType.tagBits & TagBits.HasMissingType) != 0) {
          method.tagBits |= TagBits.HasMissingType;
        }           
        TypeBinding leafType = parameterType.leafComponentType();
        if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
          method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
        newParameters[i] = parameterType;
        arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true);
      }
    }
    // only assign parameters if no problems are found
    if (!foundArgProblem) {
      method.parameters = newParameters;
    }
  }

  boolean foundReturnTypeProblem = false;
  if (!method.isConstructor()) {
    TypeReference returnType = methodDecl instanceof MethodDeclaration
      ? ((MethodDeclaration) methodDecl).returnType
      : null;
    if (returnType == null) {
      methodDecl.scope.problemReporter().missingReturnType(methodDecl);
      method.returnType = null;
      foundReturnTypeProblem = true;
    } else {
      TypeBinding methodType = returnType.resolveType(methodDecl.scope, true /* check bounds*/);
      if (methodType == null) {
        foundReturnTypeProblem = true;
      } else if (methodType.isArrayType() && ((ArrayBinding) methodType).leafComponentType == TypeBinding.VOID) {
        methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray((MethodDeclaration) methodDecl);
        foundReturnTypeProblem = true;
      } else {
        if ((methodType.tagBits & TagBits.HasMissingType) != 0) {
          method.tagBits |= TagBits.HasMissingType;
        }         
        method.returnType = methodType;
        TypeBinding leafType = methodType.leafComponentType();
        if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
          method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
      }
    }
  }
  if (foundArgProblem) {
    methodDecl.binding = null;
    method.parameters = Binding.NO_PARAMETERS; // see 107004
    // nullify type parameter bindings as well as they have a backpointer to the method binding
    // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=81134)
    if (typeParameters != null)
      for (int i = 0, length = typeParameters.length; i < length; i++)
        typeParameters[i].binding = null;
    return null;
  }
  if (foundReturnTypeProblem)
    return method; // but its still unresolved with a null return type & is still connected to its method declaration

  method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
  return method;
}
public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
  if (forceInitialization)
    binding.getAnnotationTagBits(); // ensure annotations are up to date
  return super.retrieveAnnotationHolder(binding, false);
}
public void setFields(FieldBinding[] fields) {
  this.fields = fields;
}
public void setMethods(MethodBinding[] methods) {
  this.methods = methods;
}
public final int sourceEnd() {
  return this.scope.referenceContext.sourceEnd;
}
public final int sourceStart() {
  return this.scope.referenceContext.sourceStart;
}
SimpleLookupTable storedAnnotations(boolean forceInitialize) {
  if (forceInitialize && this.storedAnnotations == null && this.scope != null) { // scope null when no annotation cached, and type got processed fully (159631)
    this.scope.referenceCompilationUnit().compilationResult.hasAnnotations = true;
    if (!this.scope.environment().globalOptions.storeAnnotations)
      return null; // not supported during this compile
    this.storedAnnotations = new SimpleLookupTable(3);
  }
  return this.storedAnnotations;
}
public ReferenceBinding superclass() {
  return this.superclass;
}
public ReferenceBinding[] superInterfaces() {
  return this.superInterfaces;
}
// TODO (philippe) could be a performance issue since some senders are building the list just to count them
public SyntheticMethodBinding[] syntheticMethods() {
  
  if (this.synthetics == null || this.synthetics[SourceTypeBinding.METHOD_EMUL] == null || this.synthetics[SourceTypeBinding.METHOD_EMUL].size() == 0) return null;

  // difficult to compute size up front because of the embedded arrays so assume there is only 1
  int index = 0;
  SyntheticMethodBinding[] bindings = new SyntheticMethodBinding[1];
  Iterator fieldsOrMethods = this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator();
  while (fieldsOrMethods.hasNext()) {

    Object fieldOrMethod = fieldsOrMethods.next();

    if (fieldOrMethod instanceof MethodBinding) {

      SyntheticMethodBinding[] methodAccessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(fieldOrMethod);
      int numberOfAccessors = 0;
      if (methodAccessors[0] != null) numberOfAccessors++;
      if (methodAccessors[1] != null) numberOfAccessors++;
      if (index + numberOfAccessors > bindings.length)
        System.arraycopy(bindings, 0, (bindings = new SyntheticMethodBinding[index + numberOfAccessors]), 0, index);
      if (methodAccessors[0] != null) 
        bindings[index++] = methodAccessors[0]; // super access 
      if (methodAccessors[1] != null) 
        bindings[index++] = methodAccessors[1]; // normal access or bridge

    } else {

      SyntheticMethodBinding[] fieldAccessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(fieldOrMethod);
      int numberOfAccessors = 0;
      if (fieldAccessors[0] != null) numberOfAccessors++;
      if (fieldAccessors[1] != null) numberOfAccessors++;
      if (index + numberOfAccessors > bindings.length)
        System.arraycopy(bindings, 0, (bindings = new SyntheticMethodBinding[index + numberOfAccessors]), 0, index);
      if (fieldAccessors[0] != null) 
        bindings[index++] = fieldAccessors[0]; // read access
      if (fieldAccessors[1] != null) 
        bindings[index++] = fieldAccessors[1]; // write access
    }
  }

  // sort them in according to their own indexes
  int length;
  SyntheticMethodBinding[] sortedBindings = new SyntheticMethodBinding[length = bindings.length];
  for (int i = 0; i < length; i++){
    SyntheticMethodBinding binding = bindings[i];
    sortedBindings[binding.index] = binding;
  }
  return sortedBindings;
}
/**
 * Answer the collection of synthetic fields to append into the classfile
 */
public FieldBinding[] syntheticFields() {
  
  if (this.synthetics == null) return null;

  int fieldSize = this.synthetics[SourceTypeBinding.FIELD_EMUL] == null ? 0 : this.synthetics[SourceTypeBinding.FIELD_EMUL].size();
  int literalSize = this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null ? 0 :this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size();
  int totalSize = fieldSize + literalSize;
  if (totalSize == 0) return null;
  FieldBinding[] bindings = new FieldBinding[totalSize];

  // add innerclass synthetics
  if (this.synthetics[SourceTypeBinding.FIELD_EMUL] != null){
    Iterator elements = this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator();
    for (int i = 0; i < fieldSize; i++) {
      SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.next();
      bindings[synthBinding.index] = synthBinding;
    }
  }
  // add class literal synthetics
  if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] != null){
    Iterator elements = this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].values().iterator();
    for (int i = 0; i < literalSize; i++) {
      SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.next();
      bindings[fieldSize+synthBinding.index] = synthBinding;
    }
  }
  return bindings;
}
public String toString() {
    StringBuffer buffer = new StringBuffer(30);
    buffer.append("(id="); //$NON-NLS-1$
    if (this.id == TypeIds.NoId) 
        buffer.append("NoId"); //$NON-NLS-1$
    else 
        buffer.append(this.id);
    buffer.append(")\n"); //$NON-NLS-1$
  if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
  if (isPublic()) buffer.append("public "); //$NON-NLS-1$
  if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
  if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
  if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
  if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
  if (isFinal()) buffer.append("final "); //$NON-NLS-1$

  if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
  else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
  else if (isClass()) buffer.append("class "); //$NON-NLS-1$
  else buffer.append("interface "); //$NON-NLS-1$
  buffer.append((this.compoundName != null) ? CharOperation.toString(this.compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$

  if (this.typeVariables == null) {
    buffer.append("<NULL TYPE VARIABLES>"); //$NON-NLS-1$
  } else if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
    buffer.append("<"); //$NON-NLS-1$
    for (int i = 0, length = this.typeVariables.length; i < length; i++) {
      if (i  > 0) buffer.append(", "); //$NON-NLS-1$
      if (this.typeVariables[i] == null) {
        buffer.append("NULL TYPE VARIABLE"); //$NON-NLS-1$
        continue;
      }
      char[] varChars = this.typeVariables[i].toString().toCharArray();
      buffer.append(varChars, 1, varChars.length - 2);
    }
    buffer.append(">"); //$NON-NLS-1$
  }
  buffer.append("\n\textends "); //$NON-NLS-1$
  buffer.append((this.superclass != null) ? this.superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$

  if (this.superInterfaces != null) {
    if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
      buffer.append("\n\timplements : "); //$NON-NLS-1$
      for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
        if (i  > 0)
          buffer.append(", "); //$NON-NLS-1$
        buffer.append((this.superInterfaces[i] != null) ? this.superInterfaces[i].debugName() : "NULL TYPE"); //$NON-NLS-1$
      }
    }
  } else {
    buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
  }

  if (enclosingType() != null) {
    buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
    buffer.append(enclosingType().debugName());
  }

  if (this.fields != null) {
    if (this.fields != Binding.NO_FIELDS) {
      buffer.append("\n/*   fields   */"); //$NON-NLS-1$
      for (int i = 0, length = this.fields.length; i < length; i++)
          buffer.append('\n').append((this.fields[i] != null) ? this.fields[i].toString() : "NULL FIELD"); //$NON-NLS-1$ 
    }
  } else {
    buffer.append("NULL FIELDS"); //$NON-NLS-1$
  }

  if (this.methods != null) {
    if (this.methods != Binding.NO_METHODS) {
      buffer.append("\n/*   methods   */"); //$NON-NLS-1$
      for (int i = 0, length = this.methods.length; i < length; i++)
        buffer.append('\n').append((this.methods[i] != null) ? this.methods[i].toString() : "NULL METHOD"); //$NON-NLS-1$
    }
  } else {
    buffer.append("NULL METHODS"); //$NON-NLS-1$
  }

  if (this.memberTypes != null) {
    if (this.memberTypes != Binding.NO_MEMBER_TYPES) {
      buffer.append("\n/*   members   */"); //$NON-NLS-1$
      for (int i = 0, length = this.memberTypes.length; i < length; i++)
        buffer.append('\n').append((this.memberTypes[i] != null) ? this.memberTypes[i].toString() : "NULL TYPE"); //$NON-NLS-1$
    }
  } else {
    buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
  }

  buffer.append("\n\n"); //$NON-NLS-1$
  return buffer.toString();
}
public TypeVariableBinding[] typeVariables() {
  return this.typeVariables;
}
void verifyMethods(MethodVerifier verifier) {
  verifier.verify(this);

  for (int i = this.memberTypes.length; --i >= 0;)
     ((SourceTypeBinding) this.memberTypes[i]).verifyMethods(verifier);
}
}
