Program: 12083
Project: 12083
Buggy source:
private void processInternalMethodInvocation(ClassObject classObject,MethodObject methodObject,AbstractVariable variableDeclaration,Set<String> processedMethods){
  SystemObject systemObject=ASTReader.getSystemObject();
  if (methodObject.isAbstract() || classObject.isInterface()) {
    TypeDeclaration typeDeclaration=classObject.getTypeDeclaration();
    IMethodBinding superMethodDeclarationBinding=methodObject.getMethodDeclaration().resolveBinding();
    IType superType=(IType)typeDeclaration.resolveBinding().getJavaElement();
    processedMethods.add(superMethodDeclarationBinding.getKey());
    Set<IType> subTypes=CompilationUnitCache.getInstance().getSubTypes(superType);
    Set<IType> subTypesToBeAnalyzed=new LinkedHashSet<IType>();
    if (variableDeclaration != null) {
      String initialReferenceType=variableDeclaration.getVariableType();
      for (      IType subType : subTypes) {
        if (subType.getFullyQualifiedName('.').equals(initialReferenceType)) {
          subTypesToBeAnalyzed.add(subType);
          break;
        }
      }
      if (subTypesToBeAnalyzed.isEmpty())       subTypesToBeAnalyzed.addAll(subTypes);
    }
 else     subTypesToBeAnalyzed.addAll(subTypes);
    for (    IType subType : subTypesToBeAnalyzed) {
      ClassObject subClassObject=systemObject.getClassObject(subType.getFullyQualifiedName('.'));
      if (subClassObject != null) {
        ListIterator<MethodObject> methodIterator=subClassObject.getMethodIterator();
        while (methodIterator.hasNext()) {
          MethodObject subMethod=methodIterator.next();
          if (equalSignature(subMethod.getMethodDeclaration().resolveBinding(),superMethodDeclarationBinding)) {
            processInternalMethodInvocation(subClassObject,subMethod,variableDeclaration,processedMethods);
            break;
          }
        }
      }
    }
  }
 else {
    for (    PlainVariable originalField : methodObject.getDefinedFieldsThroughThisReference()) {
      boolean alreadyContainsOriginalField=false;
      if (variableDeclaration != null && originalField instanceof PlainVariable) {
        if (variableDeclaration.containsPlainVariable((PlainVariable)originalField))         alreadyContainsOriginalField=true;
      }
      if (!alreadyContainsOriginalField) {
        AbstractVariable field=null;
        if (variableDeclaration != null)         field=composeVariable(variableDeclaration,originalField);
 else         field=originalField;
        definedVariables.add(field);
      }
    }
    for (    PlainVariable originalField : methodObject.getUsedFieldsThroughThisReference()) {
      boolean alreadyContainsOriginalField=false;
      if (variableDeclaration != null && originalField instanceof PlainVariable) {
        if (variableDeclaration.containsPlainVariable((PlainVariable)originalField))         alreadyContainsOriginalField=true;
      }
      if (!alreadyContainsOriginalField) {
        AbstractVariable field=null;
        if (variableDeclaration != null)         field=composeVariable(variableDeclaration,originalField);
 else         field=originalField;
        usedVariables.add(field);
      }
    }
    thrownExceptionTypes.addAll(methodObject.getExceptionsInThrowStatements());
    processedMethods.add(methodObject.getMethodDeclaration().resolveBinding().getKey());
    Map<AbstractVariable,LinkedHashSet<MethodInvocationObject>> invokedMethodsThroughFields=methodObject.getInvokedMethodsThroughFields();
    for (    AbstractVariable originalField : invokedMethodsThroughFields.keySet()) {
      boolean alreadyContainsOriginalField=false;
      if (variableDeclaration != null && originalField instanceof PlainVariable) {
        if (variableDeclaration.containsPlainVariable((PlainVariable)originalField))         alreadyContainsOriginalField=true;
      }
      if (!alreadyContainsOriginalField) {
        LinkedHashSet<MethodInvocationObject> methodInvocations=invokedMethodsThroughFields.get(originalField);
        AbstractVariable field=null;
        if (variableDeclaration != null)         field=composeVariable(variableDeclaration,originalField);
 else         field=originalField;
        for (        MethodInvocationObject methodInvocationObject : methodInvocations) {
          MethodInvocation methodInvocation2=methodInvocationObject.getMethodInvocation();
          ClassObject classObject2=systemObject.getClassObject(methodInvocationObject.getOriginClassName());
          if (classObject2 != null) {
            MethodObject methodObject2=classObject2.getMethod(methodInvocationObject);
            if (methodObject2 != null) {
              processInternalMethodInvocation(classObject2,methodObject2,field,new LinkedHashSet<String>());
            }
          }
 else {
            LibraryClassStorage instance=LibraryClassStorage.getInstance();
            IMethodBinding invokedMethodBinding=methodInvocation2.resolveMethodBinding();
            if (instance.isAnalyzed(invokedMethodBinding.getKey())) {
              handleAlreadyAnalyzedMethod(invokedMethodBinding.getKey(),field,instance);
            }
 else {
              MethodDeclaration invokedMethodDeclaration=getInvokedMethodDeclaration(invokedMethodBinding);
              if (invokedMethodDeclaration != null)               processExternalMethodInvocation(invokedMethodDeclaration,field,new LinkedHashSet<String>(),0);
            }
          }
        }
      }
    }
    for (    MethodInvocationObject methodInvocationObject : methodObject.getInvokedMethodsThroughThisReference()) {
      MethodObject methodObject2=classObject.getMethod(methodInvocationObject);
      if (methodObject2 != null) {
        if (!methodObject2.equals(methodObject)) {
          MethodInvocation methodInvocation2=methodInvocationObject.getMethodInvocation();
          if (!processedMethods.contains(methodInvocation2.resolveMethodBinding().getKey()))           processInternalMethodInvocation(classObject,methodObject2,variableDeclaration,processedMethods);
        }
      }
 else {
        ClassObject classObject2=systemObject.getClassObject(methodInvocationObject.getOriginClassName());
        if (classObject2 != null) {
          methodObject2=classObject2.getMethod(methodInvocationObject);
          if (methodObject2 != null) {
            thrownExceptionTypes.addAll(methodObject2.getExceptionsInThrowStatements());
          }
        }
      }
    }
    for (    SuperMethodInvocationObject superMethodInvocationObject : methodObject.getSuperMethodInvocations()) {
      ClassObject classObject2=systemObject.getClassObject(superMethodInvocationObject.getOriginClassName());
      if (classObject2 != null) {
        MethodObject methodObject2=classObject2.getMethod(superMethodInvocationObject);
        if (methodObject2 != null) {
          SuperMethodInvocation superMethodInvocation=superMethodInvocationObject.getSuperMethodInvocation();
          if (!processedMethods.contains(superMethodInvocation.resolveMethodBinding().getKey()))           processInternalMethodInvocation(classObject2,methodObject2,variableDeclaration,processedMethods);
        }
      }
    }
  }
}

Fixed version (ground truth):
private void processInternalMethodInvocation(ClassObject classObject,MethodObject methodObject,AbstractVariable variableDeclaration,Set<String> processedMethods){
  SystemObject systemObject=ASTReader.getSystemObject();
  if (methodObject.isAbstract() || classObject.isInterface()) {
    TypeDeclaration typeDeclaration=classObject.getTypeDeclaration();
    IMethodBinding superMethodDeclarationBinding=methodObject.getMethodDeclaration().resolveBinding();
    IType superType=(IType)typeDeclaration.resolveBinding().getJavaElement();
    processedMethods.add(superMethodDeclarationBinding.getKey());
    Set<IType> subTypes=CompilationUnitCache.getInstance().getSubTypes(superType);
    Set<IType> subTypesToBeAnalyzed=new LinkedHashSet<IType>();
    if (variableDeclaration != null) {
      String initialReferenceType=variableDeclaration.getVariableType();
      for (      IType subType : subTypes) {
        if (subType.getFullyQualifiedName('.').equals(initialReferenceType)) {
          subTypesToBeAnalyzed.add(subType);
          break;
        }
      }
      if (subTypesToBeAnalyzed.isEmpty())       subTypesToBeAnalyzed.addAll(subTypes);
    }
 else     subTypesToBeAnalyzed.addAll(subTypes);
    for (    IType subType : subTypesToBeAnalyzed) {
      ClassObject subClassObject=systemObject.getClassObject(subType.getFullyQualifiedName('.'));
      if (subClassObject != null) {
        ListIterator<MethodObject> methodIterator=subClassObject.getMethodIterator();
        while (methodIterator.hasNext()) {
          MethodObject subMethod=methodIterator.next();
          if (equalSignature(subMethod.getMethodDeclaration().resolveBinding(),superMethodDeclarationBinding)) {
            processInternalMethodInvocation(subClassObject,subMethod,variableDeclaration,processedMethods);
            break;
          }
        }
      }
    }
  }
 else {
    for (    PlainVariable originalField : methodObject.getDefinedFieldsThroughThisReference()) {
      boolean alreadyContainsOriginalField=false;
      if (variableDeclaration != null && originalField instanceof PlainVariable) {
        if (variableDeclaration.containsPlainVariable((PlainVariable)originalField))         alreadyContainsOriginalField=true;
      }
      if (!alreadyContainsOriginalField) {
        AbstractVariable field=null;
        if (variableDeclaration != null)         field=composeVariable(variableDeclaration,originalField);
 else         field=originalField;
        definedVariables.add(field);
      }
    }
    for (    PlainVariable originalField : methodObject.getUsedFieldsThroughThisReference()) {
      boolean alreadyContainsOriginalField=false;
      if (variableDeclaration != null && originalField instanceof PlainVariable) {
        if (variableDeclaration.containsPlainVariable((PlainVariable)originalField))         alreadyContainsOriginalField=true;
      }
      if (!alreadyContainsOriginalField) {
        AbstractVariable field=null;
        if (variableDeclaration != null)         field=composeVariable(variableDeclaration,originalField);
 else         field=originalField;
        usedVariables.add(field);
      }
    }
    thrownExceptionTypes.addAll(methodObject.getExceptionsInThrowStatements());
    processedMethods.add(methodObject.getMethodDeclaration().resolveBinding().getKey());
    Map<AbstractVariable,LinkedHashSet<MethodInvocationObject>> invokedMethodsThroughFields=methodObject.getInvokedMethodsThroughFields();
    for (    AbstractVariable originalField : invokedMethodsThroughFields.keySet()) {
      boolean alreadyContainsOriginalField=false;
      if (variableDeclaration != null && originalField instanceof PlainVariable) {
        if (variableDeclaration.containsPlainVariable((PlainVariable)originalField))         alreadyContainsOriginalField=true;
      }
      if (!alreadyContainsOriginalField) {
        LinkedHashSet<MethodInvocationObject> methodInvocations=invokedMethodsThroughFields.get(originalField);
        AbstractVariable field=null;
        if (variableDeclaration != null)         field=composeVariable(variableDeclaration,originalField);
 else         field=originalField;
        for (        MethodInvocationObject methodInvocationObject : methodInvocations) {
          MethodInvocation methodInvocation2=methodInvocationObject.getMethodInvocation();
          ClassObject classObject2=systemObject.getClassObject(methodInvocationObject.getOriginClassName());
          if (classObject2 != null) {
            MethodObject methodObject2=classObject2.getMethod(methodInvocationObject);
            if (methodObject2 != null) {
              if (!processedMethods.contains(methodInvocation2.resolveMethodBinding().getKey()))               processInternalMethodInvocation(classObject2,methodObject2,field,new LinkedHashSet<String>());
            }
          }
 else {
            LibraryClassStorage instance=LibraryClassStorage.getInstance();
            IMethodBinding invokedMethodBinding=methodInvocation2.resolveMethodBinding();
            if (instance.isAnalyzed(invokedMethodBinding.getKey())) {
              handleAlreadyAnalyzedMethod(invokedMethodBinding.getKey(),field,instance);
            }
 else {
              MethodDeclaration invokedMethodDeclaration=getInvokedMethodDeclaration(invokedMethodBinding);
              if (invokedMethodDeclaration != null)               processExternalMethodInvocation(invokedMethodDeclaration,field,new LinkedHashSet<String>(),0);
            }
          }
        }
      }
    }
    for (    MethodInvocationObject methodInvocationObject : methodObject.getInvokedMethodsThroughThisReference()) {
      MethodObject methodObject2=classObject.getMethod(methodInvocationObject);
      if (methodObject2 != null) {
        if (!methodObject2.equals(methodObject)) {
          MethodInvocation methodInvocation2=methodInvocationObject.getMethodInvocation();
          if (!processedMethods.contains(methodInvocation2.resolveMethodBinding().getKey()))           processInternalMethodInvocation(classObject,methodObject2,variableDeclaration,processedMethods);
        }
      }
 else {
        ClassObject classObject2=systemObject.getClassObject(methodInvocationObject.getOriginClassName());
        if (classObject2 != null) {
          methodObject2=classObject2.getMethod(methodInvocationObject);
          if (methodObject2 != null) {
            thrownExceptionTypes.addAll(methodObject2.getExceptionsInThrowStatements());
          }
        }
      }
    }
    for (    SuperMethodInvocationObject superMethodInvocationObject : methodObject.getSuperMethodInvocations()) {
      ClassObject classObject2=systemObject.getClassObject(superMethodInvocationObject.getOriginClassName());
      if (classObject2 != null) {
        MethodObject methodObject2=classObject2.getMethod(superMethodInvocationObject);
        if (methodObject2 != null) {
          SuperMethodInvocation superMethodInvocation=superMethodInvocationObject.getSuperMethodInvocation();
          if (!processedMethods.contains(superMethodInvocation.resolveMethodBinding().getKey()))           processInternalMethodInvocation(classObject2,methodObject2,variableDeclaration,processedMethods);
        }
      }
    }
  }
}