diff --git a/contrib/bcel/docs/BCELConfig.xml b/contrib/bcel/docs/BCELConfig.xml
new file mode 100644
index 000000000..14c034513
--- /dev/null
+++ b/contrib/bcel/docs/BCELConfig.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/AbstractCheckVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/AbstractCheckVisitor.java
new file mode 100644
index 000000000..368c8521f
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/AbstractCheckVisitor.java
@@ -0,0 +1,115 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+import java.util.Set;
+
+import com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter;
+import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
+import com.puppycrawl.tools.checkstyle.api.LocalizedMessages;
+
+/**
+ * Abstract class for checks with visitors.
+ * @author Rick Giles
+ */
+//TODO: Refactor with class Check
+public abstract class AbstractCheckVisitor
+ extends AbstractViolationReporter
+ implements IObjectSetVisitor
+{
+ /** the object for collecting messages. */
+ private LocalizedMessages mMessages;
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IParserCheck */
+ public org.apache.bcel.classfile.Visitor getClassFileVisitor()
+ {
+ return new EmptyClassFileVisitor();
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.bcel.IParserCheck
+ */
+ public org.apache.bcel.generic.Visitor getGenericVisitor()
+ {
+ return new EmptyGenericVisitor();
+ }
+
+ /**
+ * Initialse the check. This is the time to verify that the check has
+ * everything required to perform it job.
+ */
+ public void init()
+ {
+ }
+
+ /**
+ * Destroy the check. It is being retired from service.
+ */
+ public void destroy()
+ {
+ }
+
+ /**
+ * Set the global object used to collect messages.
+ * @param aMessages the messages to log with
+ */
+ public final void setMessages(LocalizedMessages aMessages)
+ {
+ mMessages = aMessages;
+ }
+
+ /**
+ * Log an error message.
+ *
+ * @param aLine the line number where the error was found
+ * @param aKey the message that describes the error
+ * @param aArgs the details of the message
+ *
+ * @see java.text.MessageFormat
+ */
+ protected final void log(int aLine, String aKey, Object aArgs[])
+ {
+ mMessages.add(
+ new LocalizedMessage(
+ aLine,
+ getMessageBundle(),
+ aKey,
+ aArgs,
+ getSeverityLevel(),
+ this.getClass().getName()));
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
+ */
+ protected void log(int aLine, int aCol, String aKey, Object[] aArgs)
+ {
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void visitObject(Object aObject)
+ {
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void leaveObject(Object aObject)
+ {
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void visitSet(Set aJavaClassDefs)
+ {
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void leaveSet(Set aJavaClassDefs)
+ {
+ }
+
+ /**
+ * Gets the deep BCEL visitor.
+ * @return the deep BCEL visitor for this check.
+ */
+ public abstract IDeepVisitor getVisitor();
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ClassFileSetCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ClassFileSetCheck.java
new file mode 100644
index 000000000..3c6c95f6c
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ClassFileSetCheck.java
@@ -0,0 +1,304 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.bcel.Repository;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Visitor;
+import org.apache.bcel.util.ClassLoaderRepository;
+
+import com.puppycrawl.tools.checkstyle.DefaultContext;
+import com.puppycrawl.tools.checkstyle.ModuleFactory;
+import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.Configuration;
+import com.puppycrawl.tools.checkstyle.api.Context;
+import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
+
+/**
+ * Checks a set of class files using BCEL
+ * @author Rick Giles
+ */
+//TODO: Refactor with AbstractFileSetCheck and TreeWalker
+public class ClassFileSetCheck
+ extends AbstractFileSetCheck
+ implements IObjectSetVisitor
+{
+ /** visitors for BCEL parse tree walk */
+ private final Set mTreeVisitors = new HashSet();
+
+ /** all the registered checks */
+ private final Set mAllChecks = new HashSet();
+
+ /** all visitors for IObjectSetVisitor visits */
+ private final Set mObjectSetVisitors = new HashSet();
+
+ /** class loader to resolve classes with. **/
+ private ClassLoader mClassLoader;
+
+ /** context of child components */
+ private Context mChildContext;
+
+ /** a factory for creating submodules (i.e. the Checks) */
+ private ModuleFactory mModuleFactory;
+
+ /**
+ * Creates a new ClassFileSetCheck instance.
+ * Initializes the acceptable file extensions.
+ */
+ public ClassFileSetCheck()
+ {
+ setFileExtensions(new String[]{"class", "jar", "zip"});
+ }
+
+ /**
+ * Stores the class loader and makes it the Repository's class loader.
+ * @param aClassLoader class loader to resolve classes with.
+ */
+ public void setClassLoader(ClassLoader aClassLoader)
+ {
+ Repository.setRepository(new ClassLoaderRepository(aClassLoader));
+ mClassLoader = aClassLoader;
+ }
+
+ /**
+ * Sets the module factory for creating child modules (Checks).
+ * @param aModuleFactory the factory
+ */
+ public void setModuleFactory(ModuleFactory aModuleFactory)
+ {
+ mModuleFactory = aModuleFactory;
+ }
+
+ /**
+ * Instantiates, configures and registers a Check that is specified
+ * in the provided configuration.
+ * @see com.puppycrawl.tools.checkstyle.api.AutomaticBean
+ */
+ public void setupChild(Configuration aChildConf)
+ throws CheckstyleException
+ {
+ // TODO: improve the error handing
+ final String name = aChildConf.getName();
+ final Object module = mModuleFactory.createModule(name);
+ if (!(module instanceof AbstractCheckVisitor)) {
+ throw new CheckstyleException(
+ "ClassFileSet is not allowed as a parent of " + name);
+ }
+ final AbstractCheckVisitor c = (AbstractCheckVisitor) module;
+ c.contextualize(mChildContext);
+ c.configure(aChildConf);
+ c.init();
+
+ registerCheck(c);
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.api.Configurable */
+ public void finishLocalSetup()
+ {
+ DefaultContext checkContext = new DefaultContext();
+ checkContext.add("classLoader", mClassLoader);
+ checkContext.add("messages", getMessageCollector());
+ checkContext.add("severity", getSeverity());
+
+ mChildContext = checkContext;
+ }
+
+ /**
+ * Register a check.
+ * @param aCheck the check to register
+ */
+ private void registerCheck(AbstractCheckVisitor aCheck)
+ {
+ mAllChecks.add(aCheck);
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.api.FileSetCheck
+ */
+ public void process(File[] aFiles)
+ {
+ registerVisitors();
+
+ // get all the JavaClasses in the files
+ final Set javaClasses = extractJavaClasses(aFiles);
+
+ visitSet(javaClasses);
+
+ // walk each Java class parse tree
+ final JavaClassWalker walker = JavaClassWalker.getInstance();
+ walker.setVisitor(getTreeVisitor());
+ final Iterator it = javaClasses.iterator();
+ while (it.hasNext()) {
+ final JavaClass clazz = (JavaClass) it.next();
+ visitObject(clazz);
+ walker.walk(clazz);
+ leaveObject(clazz);
+ }
+
+ leaveSet(javaClasses);
+ fireErrors();
+ }
+
+ /**
+ * Gets the visitor for a parse tree walk.
+ * @return the visitor for a parse tree walk.
+ */
+ private Visitor getTreeVisitor()
+ {
+ return new VisitorSet(mTreeVisitors);
+ }
+
+ /**
+ * Registers all the visitors for IObjectSetVisitor visits, and for
+ * tree walk visits.
+ */
+ private void registerVisitors()
+ {
+ mObjectSetVisitors.addAll(mAllChecks);
+ final Iterator it = mAllChecks.iterator();
+ while (it.hasNext()) {
+ final AbstractCheckVisitor check = (AbstractCheckVisitor) it.next();
+ final IDeepVisitor visitor = check.getVisitor();
+ mObjectSetVisitors.add(visitor);
+ mTreeVisitors.add(visitor);
+ }
+ }
+
+ /**
+ * Gets the set of all visitors for all the checks.
+ * @return the set of all visitors for all the checks.
+ */
+ private Set getObjectSetVisitors()
+ {
+ return mObjectSetVisitors;
+ }
+
+ /**
+ * Gets the set of all JavaClasses within a set of Files.
+ * @param aFiles the set of files to extract from.
+ * @return the set of all JavaClasses within aFiles.
+ */
+ private Set extractJavaClasses(File[] aFiles)
+ {
+ final Set result = new HashSet();
+ final File[] classFiles = filter(aFiles);
+ // get Java classes from each filtered file
+ for (int i = 0; i < classFiles.length; i++) {
+ try {
+ final Set extracted = extractJavaClasses(classFiles[i]);
+ result.addAll(extracted);
+ }
+ catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return result;
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void visitSet(Set aSet)
+ {
+ // register the JavaClasses in the Repository
+ Repository.clearCache();
+ Iterator it = aSet.iterator();
+ while (it.hasNext()) {
+ final JavaClass javaClass = (JavaClass) it.next();
+ Repository.addClass(javaClass);
+ }
+
+ // visit the visitors
+ it = getObjectSetVisitors().iterator();
+ while (it.hasNext()) {
+ final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next();
+ visitor.visitSet(aSet);
+ }
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void visitObject(Object aObject)
+ {
+ final Iterator it = getObjectSetVisitors().iterator();
+ while (it.hasNext()) {
+ final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next();
+ visitor.visitObject(aObject);
+ }
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void leaveObject(Object aObject)
+ {
+ final Iterator it = getObjectSetVisitors().iterator();
+ while (it.hasNext()) {
+ final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next();
+ visitor.leaveObject(aObject);
+ }
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void leaveSet(Set aSet)
+ {
+ final Iterator it = getObjectSetVisitors().iterator();
+ while (it.hasNext()) {
+ final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next();
+ visitor.leaveSet(aSet);
+ }
+ }
+
+ /**
+ * Extracts the JavaClasses from .class, .zip, and .jar files.
+ * @param aFile the file to extract from.
+ * @return the set of JavaClasses from aFile.
+ * @throws IOException if there is an error.
+ */
+ private Set extractJavaClasses(File aFile)
+ throws IOException
+ {
+ final Set result = new HashSet();
+ final String fileName = aFile.getPath();
+ if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) {
+ final ZipFile zipFile = new ZipFile(fileName);
+ final Enumeration entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ final ZipEntry entry = (ZipEntry) entries.nextElement();
+ final String entryName = entry.getName();
+ if (entryName.endsWith(".class")) {
+ final InputStream in = zipFile.getInputStream(entry);
+ final JavaClass javaClass =
+ new ClassParser(in, entryName).parse();
+ result.add(javaClass);
+ }
+ }
+ }
+ else {
+ final JavaClass javaClass = new ClassParser(fileName).parse();
+ result.add(javaClass);
+ }
+ return result;
+ }
+
+ /**
+ * Notify all listeners about the errors in a file.
+ * Calls MessageDispatcher.fireErrors() with
+ * all logged errors and than clears errors' list.
+ */
+ private void fireErrors()
+ {
+ final LocalizedMessage[] errors = getMessageCollector().getMessages();
+ getMessageCollector().reset();
+ getMessageDispatcher().fireErrors("", errors);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyClassFileVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyClassFileVisitor.java
new file mode 100644
index 000000000..8a89c5df7
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyClassFileVisitor.java
@@ -0,0 +1,17 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+/**
+ * Default classfile visitor.
+ * @author Rick Giles
+ */
+public class EmptyClassFileVisitor
+ extends org.apache.bcel.classfile.EmptyVisitor
+{
+ /** restrict client creation */
+ protected EmptyClassFileVisitor()
+ {
+ }
+}
\ No newline at end of file
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyDeepVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyDeepVisitor.java
new file mode 100644
index 000000000..cbb7121d5
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyDeepVisitor.java
@@ -0,0 +1,86 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+import java.util.Set;
+
+
+/**
+ * Default deep visitor
+ * @author Rick Giles
+ * @version 17-Jun-2003
+ */
+public class EmptyDeepVisitor
+ implements IDeepVisitor
+{
+ /** the classfile visitor */
+ private org.apache.bcel.classfile.Visitor mClassFileVisitor =
+ new EmptyClassFileVisitor();
+
+ /** the generic visitor */
+ private org.apache.bcel.generic.Visitor mGenericVisitor =
+ new EmptyGenericVisitor();
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor
+ */
+ public org.apache.bcel.classfile.Visitor getClassFileVisitor()
+ {
+ return mClassFileVisitor;
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor
+ */
+ public org.apache.bcel.generic.Visitor getGenericVisitor()
+ {
+ return mGenericVisitor;
+ }
+
+ /**
+ * Sets the classfile visitor.
+ * @param aVisitor the classfile visitor.
+ */
+ public void setClassFileVisitor(org.apache.bcel.classfile.Visitor aVisitor)
+ {
+ mClassFileVisitor = aVisitor;
+ }
+
+ /**
+ * Sets the generic visitor.
+ * @param aVisitor the generic visitor.
+ */
+ public void setGenericVisitor(org.apache.bcel.generic.Visitor aVisitor)
+ {
+ mGenericVisitor = aVisitor;
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor
+ */
+ public void visitObject(Object aObject)
+ {
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor
+ */
+ public void leaveObject(Object aObject)
+ {
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor
+ */
+ public void visitSet(Set aSet)
+ {
+ }
+
+ /**
+ * @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor
+ */
+ public void leaveSet(Set aSet)
+ {
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyGenericVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyGenericVisitor.java
new file mode 100644
index 000000000..71be8c6af
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/EmptyGenericVisitor.java
@@ -0,0 +1,18 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+/**
+ * Default generic visitor
+ * @author Rick Giles
+ */
+public class EmptyGenericVisitor
+ extends org.apache.bcel.generic.EmptyVisitor
+{
+ /** Restrict client creation */
+ protected EmptyGenericVisitor()
+ {
+ }
+}
+
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/IDeepVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/IDeepVisitor.java
new file mode 100644
index 000000000..71c725190
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/IDeepVisitor.java
@@ -0,0 +1,25 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+/**
+ * Deep visitor for classfile and generic traversals. A ClassFile traversal
+ * visits all classfile and all generic nodes.
+ * @author Rick Giles
+ */
+public interface IDeepVisitor
+ extends IObjectSetVisitor
+{
+ /**
+ * Returns the classfile visitor.
+ * @return the classfile visitor.
+ */
+ org.apache.bcel.classfile.Visitor getClassFileVisitor();
+
+ /**
+ * Returns the generic visitor.
+ * @return the generic visitor.
+ */
+ org.apache.bcel.generic.Visitor getGenericVisitor();
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/IObjectSetVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/IObjectSetVisitor.java
new file mode 100644
index 000000000..1e492ef11
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/IObjectSetVisitor.java
@@ -0,0 +1,37 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+import java.util.Set;
+
+/**
+ * Object set visitor for a general set.
+ * @author Rick Giles
+ */
+public interface IObjectSetVisitor
+{
+ /**
+ * Visit a set itself.
+ * @param aSet the set.
+ */
+ void visitSet(Set aSet);
+
+ /**
+ * Finish the visit of a set.
+ * @param aSet the set.
+ */
+ void leaveSet(Set aSet);
+
+ /**
+ * Visit an object. Normally this is an object of the set.
+ * @param aObject the object.
+ */
+ void visitObject(Object aObject);
+
+ /**
+ * Finish the visit an object. Normally this is an object of the set.
+ * @param aObject the object.
+ */
+ void leaveObject(Object aObject);
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/JavaClassWalker.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/JavaClassWalker.java
new file mode 100644
index 000000000..3c28cb7d9
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/JavaClassWalker.java
@@ -0,0 +1,57 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+import org.apache.bcel.classfile.DescendingVisitor;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Visitor;
+
+/**
+ * Walks a JavaClass parse tree.
+ * @author Rick Giles
+ * @version 15-Jun-2003
+ */
+public final class JavaClassWalker
+{
+ /** singleton */
+ private static JavaClassWalker sInstance = new JavaClassWalker();
+
+ /** visitor to be accepted during a traversal */
+ private Visitor mVisitor = new EmptyClassFileVisitor();
+
+ /** prevent client creation */
+ private JavaClassWalker()
+ {
+ }
+
+ /**
+ * Accesses the singleton JavaClassWalker.
+ * @return the singleton JavaClassWalker.
+ */
+ public static JavaClassWalker getInstance()
+ {
+ return sInstance;
+ }
+
+ /**
+ * Sets a visitor to be accepted during a traversal.
+ * @param aVisitor the visitor to be accepted during a traversal.
+ */
+ public void setVisitor(Visitor aVisitor)
+ {
+ mVisitor = aVisitor;
+ }
+
+ /**
+ * Traverses a JavaClass parse tree and accepts all registered
+ * visitors.
+ * @param aJavaClass the root of the tree.
+ */
+ public void walk(JavaClass aJavaClass)
+ {
+ DescendingVisitor visitor =
+ new DescendingVisitor(aJavaClass, mVisitor);
+ aJavaClass.accept(visitor);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java
new file mode 100644
index 000000000..ab6f11401
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java
@@ -0,0 +1,149 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+import java.util.Set;
+
+import org.apache.bcel.classfile.ConstantPool;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.GETFIELD;
+import org.apache.bcel.generic.GETSTATIC;
+import org.apache.bcel.generic.INVOKESPECIAL;
+import org.apache.bcel.generic.INVOKESTATIC;
+import org.apache.bcel.generic.INVOKEVIRTUAL;
+import org.apache.bcel.generic.PUTFIELD;
+import org.apache.bcel.generic.PUTSTATIC;
+
+import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition;
+import com.puppycrawl.tools.checkstyle.bcel.classfile.ReferenceDAO;
+import com.puppycrawl.tools.checkstyle.bcel.generic.FieldReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.GETFIELDReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.GETSTATICReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.InvokeReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.PUTFIELDReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.PUTSTATICReference;
+
+/**
+ * Records references during a deep parse tree traversal.
+ * @author Rick Giles
+ */
+public final class ReferenceVisitor extends EmptyDeepVisitor {
+ /** singleton */
+ private static ReferenceVisitor sInstance = new ReferenceVisitor();
+
+ /** maps a JavaClass to a JavaClassDefinition */
+ private ReferenceDAO mReferenceDAO;
+
+ /** access to current constant pool */
+ private ConstantPoolGen mCurrentPoolGen;
+
+ /**
+ * Adds a reference when it visits an instruction that invokes
+ * a method or references a field.
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+ private class GenericVisitor extends org.apache.bcel.generic.EmptyVisitor {
+ /** @see org.apache.bcel.generic.Visitor */
+ public void visitINVOKESPECIAL(INVOKESPECIAL aINVOKESPECIAL) {
+ addInvokeReference(
+ new InvokeReference(aINVOKESPECIAL, mCurrentPoolGen));
+ }
+
+ /** @see org.apache.bcel.generic.Visitor */
+ public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC) {
+ addInvokeReference(
+ new InvokeReference(aINVOKESTATIC, mCurrentPoolGen));
+ }
+
+ /** @see org.apache.bcel.generic.Visitor */
+ public void visitINVOKEVIRTUAL(INVOKEVIRTUAL aINVOKEVIRTUAL) {
+ addInvokeReference(
+ new InvokeReference(aINVOKEVIRTUAL, mCurrentPoolGen));
+ }
+
+ /** @see org.apache.bcel.generic.Visitor */
+ public void visitGETSTATIC(GETSTATIC aGETSTATIC) {
+ addFieldReference(
+ new GETSTATICReference(aGETSTATIC, mCurrentPoolGen));
+ }
+
+ /** @see org.apache.bcel.generic.Visitor */
+ public void visitGETFIELD(GETFIELD aGETFIELD) {
+ addFieldReference(
+ new GETFIELDReference(aGETFIELD, mCurrentPoolGen));
+ }
+
+ /** @see org.apache.bcel.generic.Visitor */
+ public void visitPUTSTATIC(PUTSTATIC aPUTSTATIC) {
+ addFieldReference(
+ new PUTSTATICReference(aPUTSTATIC, mCurrentPoolGen));
+ }
+
+ /** @see org.apache.bcel.generic.Visitor */
+ public void visitPUTFIELD(PUTFIELD aPUTFIELD) {
+ addFieldReference(
+ new PUTFIELDReference(aPUTFIELD, mCurrentPoolGen));
+ }
+ }
+
+ /** prevent client construction */
+ private ReferenceVisitor() {
+ setGenericVisitor(new GenericVisitor());
+ }
+
+ /**
+ * Returns the singleton ReferencesVisitor
+ * @return the singleton
+ */
+ public static ReferenceVisitor getInstance() {
+ return sInstance;
+ }
+
+ /**
+ * Adds an invoke reference to the reference DAO.
+ * @param aReference the reference.
+ */
+ private void addInvokeReference(InvokeReference aReference) {
+ getReferenceDAO().addInvokeReference(aReference);
+ }
+
+ /**
+ * Adds an field reference to the reference DAO.
+ * @param aReference the reference.
+ */
+ private void addFieldReference(FieldReference aReference) {
+ getReferenceDAO().addFieldReference(aReference);
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor */
+ public void visitSet(Set aJavaClasses) {
+ mReferenceDAO = new ReferenceDAO(aJavaClasses);
+ }
+
+ /**
+ * Gets the reference DAO.
+ * @return the reference DAO.
+ */
+ public ReferenceDAO getReferenceDAO() {
+ return mReferenceDAO;
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor */
+ public void visitObject(Object aObject) {
+ final JavaClass javaClass = (JavaClass) aObject;
+ final ConstantPool pool = javaClass.getConstantPool();
+ mCurrentPoolGen = new ConstantPoolGen(pool);
+ }
+
+ /**
+ * Finds the JavaClassDefinition for a given JavaClass.
+ * @param aJavaClass the JavaClass.
+ * @return the JavaClassDefinition for aJavaClass.
+ */
+ public JavaClassDefinition findJavaClassDef(JavaClass aJavaClass) {
+ return getReferenceDAO().findJavaClassDef(aJavaClass);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/VisitorSet.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/VisitorSet.java
new file mode 100644
index 000000000..81227a2fd
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/VisitorSet.java
@@ -0,0 +1,130 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.bcel.classfile.Code;
+import org.apache.bcel.classfile.ConstantPool;
+import org.apache.bcel.classfile.EmptyVisitor;
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.LocalVariable;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.classfile.Visitor;
+import org.apache.bcel.generic.InstructionHandle;
+import org.apache.bcel.generic.InstructionList;
+
+/**
+ * Manages a set of visitors that are accepted by nodes visited by
+ * a VisitorSet. Any visit to this object is passed on to its managed
+ * visitors.
+ * @author Rick Giles
+ */
+// TODO: review visitXXX
+public class VisitorSet
+ extends EmptyVisitor
+{
+ /** the managed visitors */
+ private Set mVisitors = new HashSet();
+
+ /** Creates a VisitorSet for a set of visitors.
+ * @param aVisitors the set of managed visitors.
+ */
+ public VisitorSet(Set aVisitors)
+ {
+ mVisitors = aVisitors;
+ }
+
+ /**
+ * @see org.apache.bcel.classfile.Visitor#visitCode
+ */
+ public void visitCode(Code aCode)
+ {
+ // perform a deep visit
+ final byte[] code = aCode.getCode();
+ final InstructionList list = new InstructionList(code);
+ final Iterator it = list.iterator();
+ for (Iterator iter = list.iterator(); iter.hasNext();) {
+ InstructionHandle instruction = (InstructionHandle) iter.next();
+ visitInstructionHandle(instruction);
+ }
+ }
+
+ /**
+ * Deep visit of an InstructionHandle
+ * @param aInstruction the InstructionHandle
+ */
+ private void visitInstructionHandle(InstructionHandle aInstruction)
+ {
+ for (Iterator iter = mVisitors.iterator(); iter.hasNext();) {
+ final IDeepVisitor visitor = (IDeepVisitor) iter.next();
+ org.apache.bcel.generic.Visitor v =
+ visitor.getGenericVisitor();
+ aInstruction.accept(v);
+ }
+ }
+
+ /**
+ * @see org.apache.bcel.classfile.Visitor
+ */
+ public void visitConstantPool(ConstantPool aConstantPool)
+ {
+ for (Iterator iter = mVisitors.iterator(); iter.hasNext();) {
+ IDeepVisitor visitor = (IDeepVisitor) iter.next();
+ Visitor v = visitor.getClassFileVisitor();
+ aConstantPool.accept(v);
+ }
+ }
+
+ /**
+ * @see org.apache.bcel.classfile.Visitor
+ */
+ public void visitField(Field aField)
+ {
+ for (Iterator iter = mVisitors.iterator(); iter.hasNext();) {
+ IDeepVisitor visitor = (IDeepVisitor) iter.next();
+ Visitor v = visitor.getClassFileVisitor();
+ aField.accept(v);
+ }
+ }
+
+ /**
+ * @see org.apache.bcel.classfile.Visitor
+ */
+ public void visitJavaClass(JavaClass aJavaClass)
+ {
+ for (Iterator iter = mVisitors.iterator(); iter.hasNext();) {
+ IDeepVisitor visitor = (IDeepVisitor) iter.next();
+ Visitor v = visitor.getClassFileVisitor();
+ aJavaClass.accept(v);
+ }
+ }
+
+ /**
+ * @see org.apache.bcel.classfile.Visitor
+ */
+ public void visitLocalVariable(LocalVariable aLocalVariable)
+ {
+ for (Iterator iter = mVisitors.iterator(); iter.hasNext();) {
+ IDeepVisitor visitor = (IDeepVisitor) iter.next();
+ Visitor v = visitor.getClassFileVisitor();
+ aLocalVariable.accept(v);
+ }
+ }
+
+ /**
+ * @see org.apache.bcel.classfile.Visitor
+ */
+ public void visitMethod(Method aMethod)
+ {
+ for (Iterator iter = mVisitors.iterator(); iter.hasNext();) {
+ IDeepVisitor visitor = (IDeepVisitor) iter.next();
+ Visitor v = visitor.getClassFileVisitor();
+ aMethod.accept(v);
+ }
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/AbstractReferenceCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/AbstractReferenceCheck.java
new file mode 100644
index 000000000..a8566c922
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/AbstractReferenceCheck.java
@@ -0,0 +1,109 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.checks;
+
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.commons.beanutils.ConversionException;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import com.puppycrawl.tools.checkstyle.api.Utils;
+import com.puppycrawl.tools.checkstyle.bcel.AbstractCheckVisitor;
+import com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor;
+import com.puppycrawl.tools.checkstyle.bcel.ReferenceVisitor;
+import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition;
+import com.puppycrawl.tools.checkstyle.bcel.classfile.ReferenceDAO;
+
+/**
+ * Abstract class for checks that require reference information.
+ * @author Rick Giles
+ */
+public abstract class AbstractReferenceCheck
+ extends AbstractCheckVisitor
+{
+ /** the regexp to match class names against */
+ private RE mIgnoreClassNameRegexp;
+
+ /** the regexp to match names against */
+ private RE mIgnoreNameRegexp;
+
+ /**
+ * Creates a AbstractReferenceCheck.
+ *
+ */
+ public AbstractReferenceCheck()
+ {
+ setIgnoreClassName("^$");
+ setIgnoreName("^$");
+ }
+
+ /**
+ * Determines whether a class name and name should be ignored.
+ * @param aClassName the class name.
+ * @param aName the name.
+ * @return true if aClassName and aName should be ignored.
+ */
+ protected boolean ignore(String aClassName, String aName)
+ {
+ return (mIgnoreClassNameRegexp.match(aClassName)
+ || mIgnoreNameRegexp.match(aName));
+ }
+
+ /**
+ * Set the ignore class name to the specified regular expression.
+ * @param aFormat a String value
+ * @throws ConversionException unable to parse aFormat
+ */
+ public void setIgnoreClassName(String aFormat)
+ throws ConversionException
+ {
+ try {
+ mIgnoreClassNameRegexp = Utils.getRE(aFormat);
+ }
+ catch (RESyntaxException e) {
+ throw new ConversionException("unable to parse " + aFormat, e);
+ }
+ }
+
+ /**
+ * Set the ignore name format to the specified regular expression.
+ * @param aFormat a String value
+ * @throws ConversionException unable to parse aFormat
+ */
+ public void setIgnoreName(String aFormat)
+ throws ConversionException
+ {
+ try {
+ mIgnoreNameRegexp = Utils.getRE(aFormat);
+ }
+ catch (RESyntaxException e) {
+ throw new ConversionException("unable to parse " + aFormat, e);
+ }
+ }
+
+ /** @see com.puppycrawl.tools.checkstyle.bcel.AbstractCheckVisitor */
+ public IDeepVisitor getVisitor()
+ {
+ return ReferenceVisitor.getInstance();
+ }
+
+ /**
+ * Gets the DAO that manages references for this check.
+ * @return the the DAO that manages references for this check.
+ */
+ public ReferenceDAO getReferenceDAO()
+ {
+ return ((ReferenceVisitor) getVisitor()).getReferenceDAO();
+ }
+
+ /**
+ * Finds a JavaClassDefinition for a JavaClass.
+ * @param aJavaClass the JavaClass.
+ * @return the JavaClassDefinition for aJavaClass.
+ */
+ protected JavaClassDefinition findJavaClassDef(JavaClass aJavaClass)
+ {
+ return getReferenceDAO().findJavaClassDef(aJavaClass);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadFieldCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadFieldCheck.java
new file mode 100644
index 000000000..f589749c6
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadFieldCheck.java
@@ -0,0 +1,58 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.checks;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.JavaClass;
+
+import com.puppycrawl.tools.checkstyle.bcel.classfile.FieldDefinition;
+import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition;
+
+/**
+ * Checks for unread, non-final fields
+ * @author Rick Giles
+ */
+public class UnreadFieldCheck
+ extends AbstractReferenceCheck
+{
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void leaveSet(Set aJavaClasses)
+ {
+ final Iterator it = aJavaClasses.iterator();
+ while (it.hasNext()) {
+ final JavaClass javaClass = (JavaClass) it.next();
+ final String className = javaClass.getClassName();
+ final JavaClassDefinition classDef = findJavaClassDef(javaClass);
+ final FieldDefinition[] fieldDefs = classDef.getFieldDefs();
+ for (int i = 0; i < fieldDefs.length; i++) {
+ if (fieldDefs[i].getReadReferenceCount() == 0) {
+ final Field field = fieldDefs[i].getField();
+ if (!field.isFinal()
+ && (!ignore(className, field)))
+ {
+ log(
+ 0,
+ "unread.field",
+ new Object[] {className, fieldDefs[i]});
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Determines whether a class name and Field should be ignored.
+ * Normally the Field is a Field of the named class.
+ * @param aClassName the class name.
+ * @param aField the Field.
+ * @return true if aClassName and aField should be ignored.
+ */
+ protected boolean ignore(String aClassName, Field aField)
+ {
+ return ignore(aClassName, aField.getName());
+ }
+}
\ No newline at end of file
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadPrivateFieldCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadPrivateFieldCheck.java
new file mode 100644
index 000000000..2045cc0b1
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadPrivateFieldCheck.java
@@ -0,0 +1,20 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.checks;
+
+import org.apache.bcel.classfile.Field;
+
+/**
+ * Checks for unread, non-final private fields
+ * @author Rick Giles
+ */
+public class UnreadPrivateFieldCheck
+ extends UnreadFieldCheck
+{
+ /** @see UnreadFieldCheck */
+ protected boolean ignore(String aClassName, Field aField)
+ {
+ return (!aField.isPrivate() || super.ignore(aClassName, aField));
+ }
+}
\ No newline at end of file
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedMethodCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedMethodCheck.java
new file mode 100644
index 000000000..cc0f2f464
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedMethodCheck.java
@@ -0,0 +1,66 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.checks;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+
+import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition;
+import com.puppycrawl.tools.checkstyle.bcel.classfile.MethodDefinition;
+
+/**
+ * Checks for unused methods
+ * @author Rick Giles
+ */
+public class UnusedMethodCheck
+ extends AbstractReferenceCheck
+{
+ /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
+ public void leaveSet(Set aJavaClasses)
+ {
+ final Iterator it = aJavaClasses.iterator();
+ while (it.hasNext()) {
+ final JavaClass javaClass = (JavaClass) it.next();
+ final String className = javaClass.getClassName();
+ final JavaClassDefinition classDef = findJavaClassDef(javaClass);
+ final MethodDefinition[] methodDefs = classDef.getMethodDefs();
+ for (int i = 0; i < methodDefs.length; i++) {
+ if (!classDef.hasReference(methodDefs[i], getReferenceDAO())) {
+ final String methodName = methodDefs[i].getName();
+ final Method method = methodDefs[i].getMethod();
+ if (!ignore(className, method))
+ {
+ log(
+ 0,
+ "unused.method",
+ new Object[] {className, methodDefs[i]});
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Determines whether a class name and Method should be ignored.
+ * Normally the Method is a Method of the named class.
+ * @param aClassName the class name.
+ * @param aMethod the Method.
+ * @return true if aClassName and aMethod should be ignored.
+ */
+ protected boolean ignore(String aClassName, Method aMethod)
+ {
+ return ignore(aClassName, aMethod.getName());
+ }
+
+ /** @see AbstractReferenceCheck */
+ public boolean ignore(String aClassName, String aMethodName)
+ {
+ return (super.ignore(aClassName, aMethodName)
+ || aMethodName.equals("")
+ || aMethodName.equals(""));
+ }
+}
\ No newline at end of file
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedPrivateMethodCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedPrivateMethodCheck.java
new file mode 100644
index 000000000..ac1209f3b
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedPrivateMethodCheck.java
@@ -0,0 +1,20 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.checks;
+
+import org.apache.bcel.classfile.Method;
+
+/**
+ * Checks for unused private methods
+ * @author Rick Giles
+ */
+public class UnusedPrivateMethodCheck
+ extends UnusedMethodCheck
+{
+ /** @see UnusedMethodCheck */
+ protected boolean ignore(String aClassName, Method aMethod)
+ {
+ return (!aMethod.isPrivate() || super.ignore(aClassName, aMethod));
+ }
+}
\ No newline at end of file
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/messages.properties b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/messages.properties
new file mode 100644
index 000000000..986e34efc
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/messages.properties
@@ -0,0 +1,2 @@
+unread.field=Class ''{0}'', unread field ''{1}''.
+unused.method=Class ''{0}'', unused method ''{1}''.
\ No newline at end of file
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/FieldDefinition.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/FieldDefinition.java
new file mode 100644
index 000000000..bf102a8f5
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/FieldDefinition.java
@@ -0,0 +1,89 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.classfile;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.bcel.classfile.Field;
+
+import com.puppycrawl.tools.checkstyle.bcel.generic.FieldReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.PUTFIELDReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.PUTSTATICReference;
+
+/**
+ * Contains the definition of a Field and its references.
+ * @author Rick Giles
+ */
+public class FieldDefinition
+ extends FieldOrMethodDefinition
+{
+ /** the GET references for the Field */
+ private final Set mGetReferences = new HashSet();
+
+ /** the PUT references for the FSield */
+ private final Set mPutReferences = new HashSet();
+
+ /**
+ * Creates a FieldDefinition for a Field.
+ * @param aField the Field.
+ */
+ public FieldDefinition(Field aField)
+ {
+ super(aField);
+ }
+
+ /**
+ * Returns the Field for this definition.
+ * @return the Field for this definition.
+ */
+ public Field getField()
+ {
+ return (Field) getFieldOrMethod();
+ }
+
+ /**
+ * Determines the number of read, or GET, references to the Field.
+ * @return the number of read references to the Field.
+ */
+ public int getReadReferenceCount()
+ {
+ return mGetReferences.size();
+ }
+
+ /**
+ * Determines the number of write, or PUT, references to the Field.
+ * @return the number of write references to the Field.
+ */
+ public int getWriteReferenceCount()
+ {
+ return mPutReferences.size();
+ }
+
+ /**
+ * Determines the total number of references to the Field.
+ * @return the number of references to the Field.
+ */
+ public int getReferenceCount()
+ {
+ return getReadReferenceCount() + getWriteReferenceCount();
+ }
+
+ /**
+ * Adds a reference to the Field.
+ * @param aFieldRef the reference.
+ */
+ public void addReference(FieldReference aFieldRef)
+ {
+ // TODO Polymorphize
+ if ((aFieldRef instanceof PUTFIELDReference)
+ || (aFieldRef instanceof PUTSTATICReference))
+ {
+ mPutReferences.add(aFieldRef);
+ }
+ else {
+ mGetReferences.add(aFieldRef);
+ }
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/FieldOrMethodDefinition.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/FieldOrMethodDefinition.java
new file mode 100644
index 000000000..68e538df9
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/FieldOrMethodDefinition.java
@@ -0,0 +1,50 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.classfile;
+
+import org.apache.bcel.classfile.FieldOrMethod;
+
+/**
+ * Contains the definition of a Field or a Method.
+ * @author Rick Giles
+ */
+public class FieldOrMethodDefinition
+{
+ /** the Field or Method */
+ private FieldOrMethod mFieldOrMethod;
+
+ /**
+ * Constructs a FieldOrMethodDefinition for a Field
+ * or a Method.
+ * @param aFieldOrMethod the Field or Method
+ */
+ protected FieldOrMethodDefinition(FieldOrMethod aFieldOrMethod)
+ {
+ mFieldOrMethod = aFieldOrMethod;
+ }
+
+ /**
+ * Returns the FieldOrMethod.
+ * @return the FieldOrMethod.
+ */
+ protected FieldOrMethod getFieldOrMethod()
+ {
+ return mFieldOrMethod;
+ }
+
+ /**
+ * Returns the name of the Field or Method.
+ * @return the name of the Field or Method.
+ */
+ public String getName()
+ {
+ return mFieldOrMethod.getName();
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString()
+ {
+ return mFieldOrMethod.toString();
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java
new file mode 100644
index 000000000..5c6a0e432
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java
@@ -0,0 +1,168 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.classfile;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.bcel.Repository;
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.Type;
+
+
+/**
+ * Contains the definition of a org.apache.bcel.classfile.JavaClass and
+ * the definitions of Methods and Fields of the JavaClass
+ * @author Rick Giles
+ */
+public class JavaClassDefinition
+{
+ /** the JavaClass */
+ private JavaClass mJavaClass;
+
+ /** the method definitions */
+ private MethodDefinition[] mMethodDefs;
+
+ /** field definitions, keyed on field name */
+ private Map mFieldDefs;
+
+ /**
+ * Creates a JavaClassDefinition from a JavaClass.
+ * @param aJavaClass the JavaClass for the definition.
+ */
+ public JavaClassDefinition(JavaClass aJavaClass)
+ {
+ mJavaClass = aJavaClass;
+
+ // store method definitions
+ final Method[] methods = aJavaClass.getMethods();
+ mMethodDefs = new MethodDefinition[methods.length];
+ for (int i = 0; i < methods.length; i++) {
+ mMethodDefs[i] = new MethodDefinition(methods[i]);
+ }
+
+ // store field definitions
+ final Field[] fields = aJavaClass.getFields();
+ mFieldDefs = new HashMap(fields.length);
+ for (int i = 0; i < fields.length; i++) {
+ mFieldDefs.put(fields[i].getName(), new FieldDefinition(fields[i]));
+ }
+ }
+
+ /**
+ * Gets the JavaClass for this definition.
+ * @return the JavaClass
+ */
+ public JavaClass getJavaClass()
+ {
+ return mJavaClass;
+ }
+
+ /**
+ * Gets the method definitions for Methods of the JavaClass.
+ * @return the method definitions for Methods of the JavaClass.
+ */
+ public MethodDefinition[] getMethodDefs()
+ {
+ return mMethodDefs;
+ }
+
+ /**
+ * Gets the field definitions for Fields of the JavaClass.
+ * @return the method definitions for Fields of the JavaClass.
+ */
+ public FieldDefinition[] getFieldDefs()
+ {
+ return (FieldDefinition[]) mFieldDefs.values().toArray(
+ new FieldDefinition[mFieldDefs.size()]);
+ }
+
+ /**
+ * Finds the narrowest method that is compatible with a method.
+ * An invocation of the given method can be resolved as an invocation
+ * of the narrowest method.
+ * @param aClassName the class for the method.
+ * @param aMethodName the name of the method.
+ * @param aArgTypes the types for the method.
+ * @return the narrowest compatible method.
+ */
+ public MethodDefinition findNarrowestMethod(
+ String aClassName,
+ String aMethodName,
+ Type[] aArgTypes)
+ {
+ MethodDefinition result = null;
+ final String javaClassName = mJavaClass.getClassName();
+ if (Repository.instanceOf(aClassName, javaClassName)) {
+ // check all
+ for (int i = 0; i < mMethodDefs.length; i++) {
+ // TODO: check access privileges
+ if (mMethodDefs[i].isCompatible(aMethodName, aArgTypes)) {
+ if (result == null) {
+ result = mMethodDefs[i];
+ }
+ //else if (mMethodDefs[i].isAsNarrow(result)) {
+ else if (result.isCompatible(mMethodDefs[i])) {
+ result = mMethodDefs[i];
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Finds a field definition.
+ * @param aFieldName the name of the field.
+ * @return the field definition named aFieldName.
+ */
+ public FieldDefinition findFieldDef(String aFieldName)
+ {
+ return (FieldDefinition) mFieldDefs.get(aFieldName);
+ }
+
+ /**
+ * Determines whether there is reference to a given Method in this JavaClass
+ * definition or a definition in a superclass.
+ * @param aMethodDef the Method to check.
+ * @param aReferenceDAO reference DAO.
+ * @return true if there is a reference to the method of aMethodDef in
+ * this JavaClass or a superclass.
+ */
+ public boolean hasReference(
+ MethodDefinition aMethodDef,
+ ReferenceDAO aReferenceDAO)
+ {
+ final String methodName = aMethodDef.getName();
+ final Type[] argTypes = aMethodDef.getArgumentTypes();
+
+ // search the inheritance hierarchy
+ JavaClass currentJavaClass = getJavaClass();
+ while (currentJavaClass != null) {
+ final JavaClassDefinition javaClassDef =
+ aReferenceDAO.findJavaClassDef(currentJavaClass);
+ if (javaClassDef != null) {
+ final MethodDefinition methodDef =
+ javaClassDef.findNarrowestMethod(
+ getJavaClass().getClassName(),
+ methodName,
+ argTypes);
+ if ((methodDef != null)
+ && (methodDef.hasReference(getJavaClass())))
+ {
+ return true;
+ }
+ }
+ currentJavaClass = currentJavaClass.getSuperClass();
+ }
+ return false;
+ }
+ /** @see comp.lang.Object#toString() */
+ public String toString()
+ {
+ return getJavaClass().toString();
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/MethodDefinition.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/MethodDefinition.java
new file mode 100644
index 000000000..3bf99a818
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/MethodDefinition.java
@@ -0,0 +1,175 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.classfile;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.bcel.Repository;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.Type;
+
+import com.puppycrawl.tools.checkstyle.bcel.generic.InvokeReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.Utils;
+
+/**
+ * Contains the definition of a Method and its references.
+ * @author Rick Giles
+ */
+public class MethodDefinition
+ extends FieldOrMethodDefinition
+{
+ /** the references to the Method */
+ private Set mReferences = new HashSet();
+
+ /**
+ * Creates a MethodDefinition for a Method.
+ * @param aMethod the Method.
+ */
+ public MethodDefinition(Method aMethod)
+ {
+ super(aMethod);
+ }
+
+ /**
+ * Gets the references to the Method.
+ * @return the references to the Method.
+ */
+ public Set getReferences()
+ {
+ return mReferences;
+ }
+
+ /**
+ * Determines the number of references to the Method.
+ * @return the number of references to the Method.
+ */
+ public int getReferenceCount()
+ {
+ return mReferences.size();
+ }
+
+ /**
+ * Returns the Method for this definition.
+ * @return the Method for this definition.
+ */
+ public Method getMethod()
+ {
+ return (Method) getFieldOrMethod();
+ }
+
+ /**
+ * Adds a reference to the Method.
+ * @param aRef the reference.
+ */
+
+ public void addReference(InvokeReference aRef)
+ {
+ mReferences.add(aRef);
+ }
+
+ /**
+ * Gets the Types of the Method's arguments.
+ * @return the argument Types.
+ */
+ public Type[] getArgumentTypes()
+ {
+ return getMethod().getArgumentTypes();
+ }
+
+ /**
+ * Determines whether a Method is compatible with the
+ * Method of this definition.
+ * @param aMethod the Method to check.
+ * @return true if aMethod is compatible with the Method
+ * of this definition.
+ */
+ public boolean isCompatible(Method aMethod)
+ {
+ return isCompatible(aMethod.getName(), aMethod.getArgumentTypes());
+ }
+
+ /**
+ * Determines whether a MethodDefinition is compatible with the
+ * Method of this definition.
+ * @param aMethodDef the Method definition to check.
+ * @return true if aMethod is compatible with the Method
+ * of this definition.
+ */
+ public boolean isCompatible(MethodDefinition aMethodDef)
+ {
+ return isCompatible(aMethodDef.getMethod());
+ }
+
+ /**
+ * Determines whether the Method of a MethodDefinition is as narrow
+ * as the method for this definition.
+ * Precondition: the method for this has the same name and the same
+ * number of arguments as the Method for the given MethodDefinition.
+ * @param aMethodDef the MethodDefinition to check.
+ * @return true if the Method of aMethodDef is as narrow
+ * as the method for this definition.
+ */
+ public boolean isAsNarrow(MethodDefinition aMethodDef)
+ {
+ return aMethodDef.isCompatible(this);
+// final Type[] types1 = getArgumentTypes();
+// final Type[] types2 = aMethodDef.getArgumentTypes();
+// for (int i = 0; i < types2.length; i++) {
+// if (!Utils.isCompatible(types1[i], types2[i])) {
+// return false;
+// }
+// }
+// return true;
+ }
+
+ /**
+ * Determines whether a method is compatible with the Method of
+ * this definition.
+ * @param aMethodName the name of the method to check.
+ * @param aArgTypes the method argument types.
+ * @return true if the method is compatible with the Method of
+ * this definition.
+ */
+ public boolean isCompatible(String aMethodName, Type[] aArgTypes)
+ {
+ // same name?
+ if (!getName().equals(aMethodName)) {
+ return false;
+ }
+ // compatible argument types?
+ final Type[] methodTypes = getArgumentTypes();
+ if (methodTypes.length != aArgTypes.length) {
+ return false;
+ }
+ for (int i = 0; i < aArgTypes.length; i++) {
+ if (!Utils.isCompatible(aArgTypes[i], methodTypes[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Determine whether this method definition has a reference from a class or
+ * a superclass.
+ * @param aJavaClass the JavaClass to check against.
+ * @return true if there is a reference to this method definition from a
+ * aJavaClass or a superclass of aJavaClass.
+ */
+ public boolean hasReference(JavaClass aJavaClass)
+ {
+ final Iterator it = getReferences().iterator();
+ while (it.hasNext()) {
+ final InvokeReference invokeRef = (InvokeReference) it.next();
+ final String invokeClassName = invokeRef.getClassName();
+ if (Repository.instanceOf(aJavaClass, invokeClassName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.java
new file mode 100644
index 000000000..8db06dd37
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.java
@@ -0,0 +1,138 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.classfile;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.bcel.Repository;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.generic.Type;
+
+import com.puppycrawl.tools.checkstyle.bcel.generic.FieldReference;
+import com.puppycrawl.tools.checkstyle.bcel.generic.InvokeReference;
+
+/**
+ * Accesses Method and Field references for a set of JavaClasses.
+ * @author Rick Giles
+ */
+public class ReferenceDAO
+{
+ /** maps a JavaClass to a JavaClassDefinition */
+ private Map mJavaClasses = null;
+
+ /**
+ * Creates a ReferenceDAO from a set of JavaClasses.
+ * @param aJavaClasses the set of JavaClasses for this DAO.
+ */
+ public ReferenceDAO(Set aJavaClasses)
+ {
+ mJavaClasses = new HashMap(aJavaClasses.size());
+ final Iterator it = aJavaClasses.iterator();
+ while (it.hasNext()) {
+ final JavaClass javaClass = (JavaClass) it.next();
+ final JavaClassDefinition javaClassDef =
+ new JavaClassDefinition(javaClass);
+ mJavaClasses.put(javaClass, javaClassDef);
+ }
+ }
+
+ /**
+ * Finds the JavaClassDefinition for a given JavaClass.
+ * @param aJavaClass the JavaClass.
+ * @return the JavaClassDefinition keyed on aJavaClass.
+ */
+ public JavaClassDefinition findJavaClassDef(JavaClass aJavaClass)
+ {
+ return (JavaClassDefinition) mJavaClasses.get(aJavaClass);
+ }
+
+ /**
+ * Adds a reference for an invocation in the invoked method definition.
+ * The invocation is of the form class.method(args).
+ * @param aInvokeRef the invocation reference.
+ */
+ public void addInvokeReference(InvokeReference aInvokeRef)
+ {
+ // find the class for the instruction
+ final String className = aInvokeRef.getClassName();
+ JavaClass javaClass = Repository.lookupClass(className);
+ final String methodName = aInvokeRef.getName();
+ final Type[] argTypes = aInvokeRef.getArgTypes();
+
+ // search up the class hierarchy for the class containing the
+ // method definition.
+ MethodDefinition narrowest = null;
+ while ((javaClass != null) && (narrowest == null)) {
+ final JavaClassDefinition javaClassDef =
+ (JavaClassDefinition) mJavaClasses.get(javaClass);
+ if (javaClassDef != null) {
+ // find narrowest compatible in the current class
+ narrowest =
+ javaClassDef.findNarrowestMethod(
+ className,
+ methodName,
+ argTypes);
+ if (narrowest != null) {
+ narrowest.addReference(aInvokeRef);
+ }
+ }
+ // search the parent
+ javaClass = javaClass.getSuperClass();
+ }
+ }
+
+ /**
+ * Adds a reference to a field.
+ * @param aFieldRef the field reference.
+ */
+ public void addFieldReference(FieldReference aFieldRef)
+ {
+ final String className = aFieldRef.getClassName();
+ JavaClass javaClass = Repository.lookupClass(className);
+ final String fieldName = aFieldRef.getName();
+ // search up the class hierarchy for the class containing the
+ // method definition.
+ FieldDefinition fieldDef = null;
+ while ((javaClass != null) && (fieldDef == null)) {
+ final JavaClassDefinition javaClassDef =
+ (JavaClassDefinition) mJavaClasses.get(javaClass);
+ if (javaClassDef != null) {
+ fieldDef = javaClassDef.findFieldDef(fieldName);
+ if (fieldDef != null) {
+ fieldDef.addReference(aFieldRef);
+ }
+ }
+ //search the parent
+ javaClass = javaClass.getSuperClass();
+ }
+ }
+
+ /**
+ * Finds the definition of the field of a field reference.
+ * @param aFieldRef the reference to a field.
+ * @return the definition of the field for aFieldRef.
+ */
+ public FieldDefinition findFieldDef(FieldReference aFieldRef)
+ {
+ final String className = aFieldRef.getClassName();
+ JavaClass javaClass = Repository.lookupClass(className);
+ final String fieldName = aFieldRef.getName();
+ // search up the class hierarchy for the class containing the
+ // method definition.
+ FieldDefinition result = null;
+ while ((javaClass != null) && (result == null)) {
+ final JavaClassDefinition javaClassDef =
+ (JavaClassDefinition) mJavaClasses.get(javaClass);
+ if (javaClassDef != null) {
+ result = javaClassDef.findFieldDef(fieldName);
+ }
+ //search the parent
+ javaClass = javaClass.getSuperClass();
+ }
+ return result;
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/FieldOrMethodReference.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/FieldOrMethodReference.java
new file mode 100644
index 000000000..7aa0e4be7
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/FieldOrMethodReference.java
@@ -0,0 +1,61 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.FieldOrMethod;
+import org.apache.bcel.generic.ObjectType;
+
+/**
+ * Describe class InstructionReference
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+public class FieldOrMethodReference
+{
+ protected FieldOrMethod mInstruction;
+
+ protected ConstantPoolGen mPoolGen;
+
+ protected FieldOrMethodReference(
+ FieldOrMethod aInstruction,
+ ConstantPoolGen aPoolGen)
+ {
+ mInstruction = aInstruction;
+ mPoolGen = aPoolGen;
+ }
+
+ /**
+ * @return
+ */
+ public FieldOrMethod getInstruction()
+ {
+ return mInstruction;
+ }
+
+ public String getClassName()
+ {
+ return mInstruction.getClassName(mPoolGen);
+ }
+
+ public ObjectType getClassType()
+ {
+ return mInstruction.getClassType(mPoolGen);
+ }
+
+ public ObjectType getLoadClassType()
+ {
+ return mInstruction.getLoadClassType(mPoolGen);
+ }
+
+ public String getName()
+ {
+ return mInstruction.getName(mPoolGen);
+ }
+
+ public String toString()
+ {
+ return mInstruction.toString(mPoolGen.getConstantPool());
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/FieldReference.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/FieldReference.java
new file mode 100644
index 000000000..cda5f907e
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/FieldReference.java
@@ -0,0 +1,22 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.FieldInstruction;
+
+/**
+ * Describe class FieldReference
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+public class FieldReference extends FieldOrMethodReference
+{
+ protected FieldReference(
+ FieldInstruction aInstruction,
+ ConstantPoolGen aPoolGen)
+ {
+ super(aInstruction, aPoolGen);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/GETFIELDReference.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/GETFIELDReference.java
new file mode 100644
index 000000000..b0cd399b1
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/GETFIELDReference.java
@@ -0,0 +1,28 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.GETFIELD;
+
+/**
+ * Describe class GETFIELDReference
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+public class GETFIELDReference
+ extends FieldReference
+{
+
+ /**
+ * @param aInstruction
+ * @param aPoolGen
+ */
+ public GETFIELDReference(
+ GETFIELD aInstruction,
+ ConstantPoolGen aPoolGen)
+ {
+ super(aInstruction, aPoolGen);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/GETSTATICReference.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/GETSTATICReference.java
new file mode 100644
index 000000000..a3e46deb9
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/GETSTATICReference.java
@@ -0,0 +1,28 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.GETSTATIC;
+
+/**
+ * Describe class GETSTATICReference
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+public class GETSTATICReference
+ extends FieldReference
+{
+
+ /**
+ * @param aInstruction
+ * @param aPoolGen
+ */
+ public GETSTATICReference(
+ GETSTATIC aInstruction,
+ ConstantPoolGen aPoolGen)
+ {
+ super(aInstruction, aPoolGen);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/InvokeReference.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/InvokeReference.java
new file mode 100644
index 000000000..6eb5e68e3
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/InvokeReference.java
@@ -0,0 +1,38 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.InvokeInstruction;
+import org.apache.bcel.generic.Type;
+
+
+/**
+ * Describe class MethodReference
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+public class InvokeReference
+ extends FieldOrMethodReference
+{
+
+ /**
+ * @param aInstruction
+ * @param aPoolGen
+ */
+ public InvokeReference(
+ InvokeInstruction aInstruction,
+ ConstantPoolGen aPoolGen)
+ {
+ super(aInstruction, aPoolGen);
+ }
+
+ /**
+ * @return
+ */
+ public Type[] getArgTypes()
+ {
+ return ((InvokeInstruction) mInstruction).getArgumentTypes(mPoolGen);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/PUTFIELDReference.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/PUTFIELDReference.java
new file mode 100644
index 000000000..81dcdb824
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/PUTFIELDReference.java
@@ -0,0 +1,28 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.PUTFIELD;
+
+/**
+ * Describe class GETFIELDReference
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+public class PUTFIELDReference
+ extends FieldReference
+{
+
+ /**
+ * @param aInstruction
+ * @param aPoolGen
+ */
+ public PUTFIELDReference(
+ PUTFIELD aInstruction,
+ ConstantPoolGen aPoolGen)
+ {
+ super(aInstruction, aPoolGen);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/PUTSTATICReference.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/PUTSTATICReference.java
new file mode 100644
index 000000000..bda78fba1
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/PUTSTATICReference.java
@@ -0,0 +1,28 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.PUTSTATIC;
+
+/**
+ * Describe class GETSTATICReference
+ * @author Rick Giles
+ * @version 18-Jun-2003
+ */
+public class PUTSTATICReference
+ extends FieldReference
+{
+
+ /**
+ * @param aInstruction
+ * @param aPoolGen
+ */
+ public PUTSTATICReference(
+ PUTSTATIC aInstruction,
+ ConstantPoolGen aPoolGen)
+ {
+ super(aInstruction, aPoolGen);
+ }
+}
diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/Utils.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/Utils.java
new file mode 100644
index 000000000..4e0a108c0
--- /dev/null
+++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/generic/Utils.java
@@ -0,0 +1,71 @@
+//Tested with BCEL-5.1
+//http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
+
+package com.puppycrawl.tools.checkstyle.bcel.generic;
+
+import org.apache.bcel.generic.ReferenceType;
+import org.apache.bcel.generic.Type;
+
+/**
+ * Utility methods.
+ * @author Rick Giles
+ * @version 17-Jun-2003
+ */
+public class Utils
+{
+ /**
+ * Tests whether one type is compatible with another for method
+ * invocation conversion. This includes assignment conversion,
+ * except the implicit narrowing of integer constants.
+ * JLS Section 5.2
+ * @param aSubType the type to be converted.
+ * @param aSuperType the converted type.
+ * @return true if aSubType can be converted to aSuperType.
+ */
+ public static boolean isCompatible(Type aSubType, Type aSuperType)
+ {
+ boolean result = false;
+
+ if (aSubType.equals(aSuperType)) {
+ // identity conversion
+ result = true;
+ }
+ else if ((aSubType instanceof ReferenceType)
+ && (aSuperType instanceof ReferenceType))
+ {
+ // widening reference conversion?
+ final ReferenceType aSubRefType = (ReferenceType) aSubType;
+ result = aSubRefType.isAssignmentCompatibleWith(aSuperType);
+ }
+ // widening primitive conversion?
+ else if (aSubType.equals(Type.BYTE)) {
+ result =
+ aSuperType.equals(Type.SHORT)
+ || aSuperType.equals(Type.INT)
+ || aSuperType.equals(Type.LONG)
+ || aSuperType.equals(Type.FLOAT)
+ || aSuperType.equals(Type.DOUBLE);
+ }
+ else if (aSubType.equals(Type.SHORT)) {
+ result =
+ aSuperType.equals(Type.INT)
+ || aSuperType.equals(Type.LONG)
+ || aSuperType.equals(Type.FLOAT)
+ || aSuperType.equals(Type.DOUBLE);
+ }
+ else if (aSubType.equals(Type.INT)) {
+ result =
+ aSuperType.equals(Type.LONG)
+ || aSuperType.equals(Type.FLOAT)
+ || aSuperType.equals(Type.DOUBLE);
+ }
+ else if (aSubType.equals(Type.LONG)) {
+ result =
+ aSuperType.equals(Type.FLOAT) || aSuperType.equals(Type.DOUBLE);
+ }
+ else if (aSubType.equals(Type.DOUBLE)) {
+ result = aSuperType.equals(Type.DOUBLE);
+ }
+ return result;
+ }
+}