/*
 * fb-contrib - Auxiliary detectors for Java programs
 * Copyright (C) 2005-2015 Kevin Lubick
 * Copyright (C) 2005-2015 Dave Brosius
 * 
 * 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 com.mebigfatguy.fbcontrib.utils;

import static org.apache.bcel.Constants.ALOAD;
import static org.apache.bcel.Constants.ALOAD_0;
import static org.apache.bcel.Constants.ALOAD_3;
import static org.apache.bcel.Constants.ASTORE;
import static org.apache.bcel.Constants.ASTORE_0;
import static org.apache.bcel.Constants.ASTORE_3;
import static org.apache.bcel.Constants.INVOKEINTERFACE;
import static org.apache.bcel.Constants.INVOKESPECIAL;
import static org.apache.bcel.Constants.INVOKESTATIC;
import static org.apache.bcel.Constants.INVOKEVIRTUAL;

import java.util.BitSet;

import org.apache.bcel.Constants;

/**
 * a collection of static methods for categorizing opcodes into groups 
 */
public class OpcodeUtils {

	private static final BitSet BRANCH_OPS = new BitSet();
	static {
		BRANCH_OPS.set(Constants.GOTO);
		BRANCH_OPS.set(Constants.GOTO_W);
		BRANCH_OPS.set(Constants.IF_ACMPEQ);		
		BRANCH_OPS.set(Constants.IF_ACMPNE);		
		BRANCH_OPS.set(Constants.IF_ICMPEQ);		
		BRANCH_OPS.set(Constants.IF_ICMPGE);		
		BRANCH_OPS.set(Constants.IF_ICMPGT);		
		BRANCH_OPS.set(Constants.IF_ICMPLE);
		BRANCH_OPS.set(Constants.IF_ICMPLT);
		BRANCH_OPS.set(Constants.IF_ICMPNE);
		BRANCH_OPS.set(Constants.IFEQ);
		BRANCH_OPS.set(Constants.IFGE);
		BRANCH_OPS.set(Constants.IFGT);
		BRANCH_OPS.set(Constants.IFLE);
		BRANCH_OPS.set(Constants.IFLT);
		BRANCH_OPS.set(Constants.IFNE);
		BRANCH_OPS.set(Constants.IFNONNULL);
		BRANCH_OPS.set(Constants.IFNULL);	
	}
	
	private OpcodeUtils(){}
	
	public static boolean isALoad(int seen) {
		return (seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3));
	}

	public static boolean isAStore(int seen) {
		return (seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3));
	}

	public static boolean isInvokeInterfaceSpecialStaticOrVirtual(int seen) {
		return (seen == INVOKESPECIAL) || (seen == INVOKEINTERFACE) || (seen == INVOKEVIRTUAL)	|| (seen == INVOKESTATIC);
	}
	
	public static boolean isBranch(int seen) {
		return BRANCH_OPS.get(seen);
	}
	
}

@@ -922,523 +922,8 @@
 s;%0A%0A
-import static org.apache.bcel.Constants.ALOAD;%0Aimport static org.apache.bcel.Constants.ALOAD_0;%0Aimport static org.apache.bcel.Constants.ALOAD_3;%0Aimport static org.apache.bcel.Constants.ASTORE;%0Aimport static org.apache.bcel.Constants.ASTORE_0;%0Aimport static org.apache.bcel.Constants.ASTORE_3;%0Aimport static org.apache.bcel.Constants.INVOKEINTERFACE;%0Aimport static org.apache.bcel.Constants.INVOKESPECIAL;%0Aimport static org.apache.bcel.Constants.INVOKESTATIC;%0Aimport static org.apache.bcel.Constants.INVOKEVIRTUAL;%0A%0A
 impo
@@ -943,16 +943,16 @@
 BitSet;%0A
+
 %0Aimport 
@@ -1084,16 +1084,37 @@
 deUtils 
+implements Constants 
 %7B%0A%0A%09priv
@@ -1187,34 +1187,24 @@
 NCH_OPS.set(
-Constants.
 GOTO);%0A%09%09BRA
@@ -1215,26 +1215,16 @@
 OPS.set(
-Constants.
 GOTO_W);
@@ -1237,34 +1237,24 @@
 NCH_OPS.set(
-Constants.
 IF_ACMPEQ);%09
@@ -1272,26 +1272,16 @@
 OPS.set(
-Constants.
 IF_ACMPN
@@ -1299,34 +1299,24 @@
 NCH_OPS.set(
-Constants.
 IF_ICMPEQ);%09
@@ -1330,34 +1330,24 @@
 NCH_OPS.set(
-Constants.
 IF_ICMPGE);%09
@@ -1361,34 +1361,24 @@
 NCH_OPS.set(
-Constants.
 IF_ICMPGT);%09
@@ -1392,34 +1392,24 @@
 NCH_OPS.set(
-Constants.
 IF_ICMPLE);%0A
@@ -1421,34 +1421,24 @@
 NCH_OPS.set(
-Constants.
 IF_ICMPLT);%0A
@@ -1454,26 +1454,16 @@
 OPS.set(
-Constants.
 IF_ICMPN
@@ -1483,26 +1483,16 @@
 OPS.set(
-Constants.
 IFEQ);%0A%09
@@ -1507,26 +1507,16 @@
 OPS.set(
-Constants.
 IFGE);%0A%09
@@ -1531,26 +1531,16 @@
 OPS.set(
-Constants.
 IFGT);%0A%09
@@ -1555,26 +1555,16 @@
 OPS.set(
-Constants.
 IFLE);%0A%09
@@ -1579,26 +1579,16 @@
 OPS.set(
-Constants.
 IFLT);%0A%09
@@ -1603,26 +1603,16 @@
 OPS.set(
-Constants.
 IFNE);%0A%09
@@ -1627,26 +1627,16 @@
 OPS.set(
-Constants.
 IFNONNUL
@@ -1660,18 +1660,8 @@
 set(
-Constants.
 IFNU
@@ -2168,32 +2168,32 @@
 nch(int seen) %7B%0A
-
 %09%09return BRANCH_
@@ -2212,10 +2212,173 @@
 );%0A%09%7D%0A%09%0A
+%09public static boolean isReturn(int seen) %7B%0A%09%09return ((seen == ARETURN) %7C%7C (seen == IRETURN) %7C%7C (seen == LRETURN) %7C%7C (seen == FRETURN) %7C%7C (seen == DRETURN));%0A%09%7D%0A%09%0A
 %7D%0A

add isReturn