Bug 403475 - Hot Code Replace drops too much frames in some cases
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java
index 0d269dd..95dc262 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -7,6 +7,7 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Yevgen Kogan - Bug 403475 - Hot Code Replace drops too much frames in some cases
  *******************************************************************************/
 package org.eclipse.jdt.internal.debug.core.hcr;
 
@@ -119,7 +120,7 @@
 	 * </ul>
 	 * after the initial timestamp.
 	 */
-	public boolean hasChanged(String methodName, String signature) {
+	public boolean hasChanged(String className, String methodName, String signature) {
 		if (!fHasHistory) {
 			return false; // optimistic: we have no history, so assume that
 							// member hasn't changed
@@ -128,11 +129,10 @@
 			return true; // pessimistic: unable to build parse trees
 		}
 		MethodSearchVisitor visitor = new MethodSearchVisitor();
-		MethodDeclaration prev = findMethod(fPrevAst, visitor, methodName,
+		MethodDeclaration prev = findMethod(fPrevAst, visitor, className, methodName,
 				signature);
 		if (prev != null) {
-			MethodDeclaration curr = findMethod(fCurrentAst, visitor,
-					methodName, signature);
+			MethodDeclaration curr = findMethod(fCurrentAst, visitor, className, methodName, signature);
 			if (curr != null) {
 				return !getMatcher().match(prev, curr);
 			}
@@ -141,8 +141,8 @@
 	}
 
 	private MethodDeclaration findMethod(CompilationUnit cu,
-			MethodSearchVisitor visitor, String name, String signature) {
-		visitor.setTargetMethod(name, signature);
+			MethodSearchVisitor visitor, String className, String name, String signature) {
+		visitor.setTargetMethod(className, name, signature);
 		cu.accept(visitor);
 		return visitor.getMatch();
 	}
@@ -155,7 +155,6 @@
 	 * in case of failure.
 	 */
 	private CompilationUnit parse(InputStream input, ICompilationUnit cu) {
-
 		char[] buffer = readString(input);
 		if (buffer != null) {
 			if (fParser == null) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java
index b1c9619..0f3a6d6 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Yevgen Kogan - Bug 403475 - Hot Code Replace drops too much frames in some cases
  *******************************************************************************/
 package org.eclipse.jdt.internal.debug.core.hcr;
 
@@ -936,7 +937,11 @@
 								.getProject();
 						delta = getDelta(compilationUnit,
 								getLastProjectBuildTime(project));
-						if (!delta.hasChanged(frame.getName(),
+						
+						String typeName = frame.getDeclaringTypeName();
+						typeName = typeName.replace('$', '.');
+						
+						if (!delta.hasChanged(typeName, frame.getName(),
 								frame.getSignature())) {
 							continue;
 						}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/MethodSearchVisitor.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/MethodSearchVisitor.java
index b8b1850..d64bd8b 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/MethodSearchVisitor.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/MethodSearchVisitor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -7,11 +7,14 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Yevgen Kogan - Bug 403475 - Hot Code Replace drops too much frames in some cases
  *******************************************************************************/
 package org.eclipse.jdt.internal.debug.core.hcr;
 
 import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
 import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
@@ -105,6 +108,10 @@
 public class MethodSearchVisitor extends ASTVisitor {
 
 	/**
+	 * Class the method belongs to
+	 */
+	private String fClassName;
+	/**
 	 * Method to search for
 	 */
 	private String fName;
@@ -123,7 +130,8 @@
 	 * @param methodSignature
 	 *            signature of the method to search for
 	 */
-	public void setTargetMethod(String methodName, String methodSignature) {
+	public void setTargetMethod(String className, String methodName, String methodSignature) {
+		fClassName = className;
 		fName = methodName;
 		fParameterTypes = Signature.getParameterTypes(methodSignature);
 		// convert parameter types same format that we get from the AST type
@@ -153,7 +161,26 @@
 	 */
 	@Override
 	public boolean visit(MethodDeclaration node) {
-		if (node.getName().getIdentifier().equals(fName)) {
+		ITypeBinding binding = null;
+		IMethodBinding mbinding = node.resolveBinding();
+		if(mbinding != null) {
+			binding = mbinding.getDeclaringClass();
+		}
+		else {
+			ASTNode parent = node.getParent();
+			if(parent instanceof AbstractTypeDeclaration) {
+				binding = ((AbstractTypeDeclaration) parent).resolveBinding();
+			}
+			else if(parent instanceof AnonymousClassDeclaration) {
+				binding = ((AnonymousClassDeclaration) parent).resolveBinding();
+			}
+		}
+		String typeName = null;
+		if (binding != null) {
+			typeName = binding.getQualifiedName();
+		}
+		// if no binding exists, the behaviour should be the same as without checking for type name
+		if (node.getName().getIdentifier().equals(fName) && (typeName == null || typeName.equals(fClassName))) {
 			IMethodBinding methodBinding = node.resolveBinding();
 			if (methodBinding != null) {
 				ITypeBinding[] typeBindings = methodBinding.getParameterTypes();