TypeBinding substituteInferenceVariable(InferenceVariable var, TypeBinding substituteType) {
   if (this.inRecursiveFunction) return this;
   this.inRecursiveFunction = true;
   try {
     boolean haveSubstitution = false;
     ReferenceBinding currentSuperclass = this.superclass;
     if (currentSuperclass != null) {
       currentSuperclass =
           (ReferenceBinding) currentSuperclass.substituteInferenceVariable(var, substituteType);
       haveSubstitution |= TypeBinding.notEquals(currentSuperclass, this.superclass);
     }
     ReferenceBinding[] currentSuperInterfaces = null;
     if (this.superInterfaces != null) {
       int length = this.superInterfaces.length;
       if (haveSubstitution)
         System.arraycopy(
             this.superInterfaces,
             0,
             currentSuperInterfaces = new ReferenceBinding[length],
             0,
             length);
       for (int i = 0; i < length; i++) {
         ReferenceBinding currentSuperInterface = this.superInterfaces[i];
         if (currentSuperInterface != null) {
           currentSuperInterface =
               (ReferenceBinding)
                   currentSuperInterface.substituteInferenceVariable(var, substituteType);
           if (TypeBinding.notEquals(currentSuperInterface, this.superInterfaces[i])) {
             if (currentSuperInterfaces == null)
               System.arraycopy(
                   this.superInterfaces,
                   0,
                   currentSuperInterfaces = new ReferenceBinding[length],
                   0,
                   length);
             currentSuperInterfaces[i] = currentSuperInterface;
             haveSubstitution = true;
           }
         }
       }
     }
     if (haveSubstitution) {
       TypeVariableBinding newVar =
           new TypeVariableBinding(
               this.sourceName, this.declaringElement, this.rank, this.environment);
       newVar.superclass = currentSuperclass;
       newVar.superInterfaces = currentSuperInterfaces;
       newVar.tagBits = this.tagBits;
       return newVar;
     }
     return this;
   } finally {
     this.inRecursiveFunction = false;
   }
 }
 public TypeVariableBinding(TypeVariableBinding prototype) {
   super(prototype);
   this.declaringElement = prototype.declaringElement;
   this.rank = prototype.rank;
   this.firstBound = prototype.firstBound;
   this.superclass = prototype.superclass;
   this.superInterfaces = Binding.NO_SUPERINTERFACES;
   if (prototype.superInterfaces != null) {
     int len = prototype.superInterfaces.length;
     if (len > 0)
       System.arraycopy(
           prototype.superInterfaces, 0, this.superInterfaces = new ReferenceBinding[len], 0, len);
   }
   this.genericTypeSignature = prototype.genericTypeSignature;
   this.environment = prototype.environment;
   prototype.tagBits |= TagBits.HasAnnotatedVariants;
   this.tagBits &= ~TagBits.HasAnnotatedVariants;
 }