/*
 * FindBugs - Find bugs in Java programs
 * Copyright (C) 2003-2005 University of Maryland
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs.detect;


import org.apache.bcel.classfile.Method;

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.BytecodeScanningDetector;
import edu.umd.cs.findbugs.StatelessDetector;
import edu.umd.cs.findbugs.TypeAnnotation;

public class EqStringTest extends BytecodeScanningDetector implements  StatelessDetector {
	boolean constantOnTOS = false;
	boolean callToInternSeen = false;
	private BugReporter bugReporter;
	// String stringOnTop;

	public EqStringTest(BugReporter bugReporter) {
		this.bugReporter = bugReporter;
	}



	@Override
		 public void visit(Method obj) {
		super.visit(obj);
		constantOnTOS = false;
		callToInternSeen = false;
	}


	@Override
		 public void sawOpcode(int seen) {

		switch (seen) {
		case LDC:
		case LDC_W:
			constantOnTOS = true;
			// stringOnTop = stringConstant;
			return;
		case INVOKEVIRTUAL:
			if (getRefConstantOperand().equals("java.lang.String.intern : ()Ljava.lang.String;")
					|| getRefConstantOperand().equals("java.lang.String.equals : (Ljava.lang.Object;)Z"))
				callToInternSeen = true;
			break;
		case IF_ACMPEQ:
		case IF_ACMPNE:
			if (constantOnTOS && !callToInternSeen)
				bugReporter.reportBug(new BugInstance(this, "ES_COMPARING_STRINGS_WITH_EQ", NORMAL_PRIORITY)
						.addClassAndMethod(this)
						.addType("Ljava/lang/String;").describe(TypeAnnotation.FOUND_ROLE)
						.addSourceLine(this, getPC()));
			break;
		default:
			break;
		}
		constantOnTOS = false;
	}
}

@@ -914,16 +914,59 @@
 ethod;%0A%0A
+import edu.umd.cs.findbugs.BugAccumulator;%0A
 import e
@@ -1343,38 +1343,79 @@
 e;%0A%09
-private BugReporter bugReporte
+boolean callToEqualsSeen = false;%0A%09private BugAccumulator bugAccumulato
 r;%0A%09
@@ -1500,19 +1500,41 @@
 .bug
-Reporter = 
+Accumulator = new BugAccumulator(
 bugR
@@ -1540,16 +1540,18 @@
 Reporter
+);
 ;%0A%09%7D%0A%0A%0A%0A
@@ -1616,16 +1616,121 @@
 t(obj);%0A
+%09%09if (callToEqualsSeen)%0A%09%09%09bugAccumulator.clearBugs();%0A%09%09else%0A%09%09%09bugAccumulator.reportAccumulatedBugs();%0A
 %09%09consta
@@ -1774,16 +1774,44 @@
  false;%0A
+%09%09callToEqualsSeen = false;%0A
 %09%7D%0A%0A%0A%09@O
@@ -2085,17 +2085,46 @@
 g;%22)
+)
 %0A%09%09%09%09
-%09%7C%7C 
+callToInternSeen = true;%0A%09%09%09if (
 getR
@@ -2200,34 +2200,130 @@
 ect;)Z%22)
-)
 %0A%09%09%09%09
-callToIntern
+    %7C%7C getRefConstantOperand().equals(%22java.lang.String.compareTo : (Ljava.lang.String;)I%22))%0A%09%09%09%09callToEquals
 Seen = t
@@ -2427,23 +2427,30 @@
 %09bug
-Reporter.report
+Accumulator.accumulate
 Bug(
@@ -2627,44 +2627,14 @@
 OLE)
-%0A%09%09%09%09%09%09.addSourceLine(this, getPC())
+, this
 );%0A%09

Don't report == on strings if the same method also using .equals or compares are strings.