Bug 344350 - [runtime][bcel] NPE in
InstructionList.getInstructionHandles()
store here the two (original) classes needing a patch
diff --git a/plugins/org.eclipse.objectteams.runtime/.classpath b/plugins/org.eclipse.objectteams.runtime/.classpath
index 304e861..bd0e74a 100644
--- a/plugins/org.eclipse.objectteams.runtime/.classpath
+++ b/plugins/org.eclipse.objectteams.runtime/.classpath
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="bcelpatchbin" path="bcelpatchsrc"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/plugins/org.eclipse.objectteams.runtime/bcelpatchsrc/org/apache/bcel/generic/BranchHandle.java b/plugins/org.eclipse.objectteams.runtime/bcelpatchsrc/org/apache/bcel/generic/BranchHandle.java
new file mode 100755
index 0000000..4aa69e8
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.runtime/bcelpatchsrc/org/apache/bcel/generic/BranchHandle.java
@@ -0,0 +1,139 @@
+/**********************************************************************
+ * This file is part of "Object Teams Runtime Environment"-Software
+ * 
+ * Copyright 2012 GK Software AG
+ * 
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	  Stephan Herrmann - Initial API and implementation
+ * 
+ * This file is based on class org.apache.bcel.generic.BranchHandle
+ * originating from the Apache BCEL project which was provided under the 
+ * Apache 2.0 license. Original Copyright from BCEL:
+ * 
+ * Copyright  2000-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); 
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License. 
+ *
+ */
+package org.apache.bcel.generic;
+
+/**
+ * BranchHandle is returned by specialized InstructionList.append() whenever a
+ * BranchInstruction is appended. This is useful when the target of this
+ * instruction is not known at time of creation and must be set later
+ * via setTarget().
+ *
+ * @see InstructionHandle
+ * @see Instruction
+ * @see InstructionList
+ * @version $Id: BranchHandle.java 386056 2006-03-15 11:31:56Z tcurdt $
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class BranchHandle extends InstructionHandle {
+
+    private BranchInstruction bi; // An alias in fact, but saves lots of casts
+
+
+    private BranchHandle(BranchInstruction i) {
+        super(i);
+        bi = i;
+    }
+
+    /** Factory methods.
+     */
+    private static BranchHandle bh_list = null; // List of reusable handles
+
+
+    static final BranchHandle getBranchHandle( BranchInstruction i ) {
+        if (bh_list == null) {
+            return new BranchHandle(i);
+        }
+        BranchHandle bh = bh_list;
+        bh_list = (BranchHandle) bh.next;
+        bh.setInstruction(i);
+        return bh;
+    }
+
+
+    /** Handle adds itself to the list of resuable handles.
+     */
+    protected void addHandle() {
+        next = bh_list;
+        bh_list = this;
+    }
+
+
+    /* Override InstructionHandle methods: delegate to branch instruction.
+     * Through this overriding all access to the private i_position field should
+     * be prevented.
+     */
+    public int getPosition() {
+        return bi.position;
+    }
+
+
+    void setPosition( int pos ) {
+        i_position = bi.position = pos;
+    }
+
+
+    protected int updatePosition( int offset, int max_offset ) {
+        int x = bi.updatePosition(offset, max_offset);
+        i_position = bi.position;
+        return x;
+    }
+
+
+    /**
+     * Pass new target to instruction.
+     */
+    public void setTarget( InstructionHandle ih ) {
+        bi.setTarget(ih);
+    }
+
+
+    /**
+     * Update target of instruction.
+     */
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
+        bi.updateTarget(old_ih, new_ih);
+    }
+
+
+    /**
+     * @return target of instruction.
+     */
+    public InstructionHandle getTarget() {
+        return bi.getTarget();
+    }
+
+
+    /** 
+     * Set new contents. Old instruction is disposed and may not be used anymore.
+     */
+    public void setInstruction( Instruction i ) {
+        super.setInstruction(i);
+        if (!(i instanceof BranchInstruction)) {
+            throw new ClassGenException("Assigning " + i
+                    + " to branch handle which is not a branch instruction");
+        }
+        bi = (BranchInstruction) i;
+    }
+}
diff --git a/plugins/org.eclipse.objectteams.runtime/bcelpatchsrc/org/apache/bcel/generic/InstructionHandle.java b/plugins/org.eclipse.objectteams.runtime/bcelpatchsrc/org/apache/bcel/generic/InstructionHandle.java
new file mode 100755
index 0000000..b0d6caa
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.runtime/bcelpatchsrc/org/apache/bcel/generic/InstructionHandle.java
@@ -0,0 +1,308 @@
+/**********************************************************************
+ * This file is part of "Object Teams Runtime Environment"-Software
+ * 
+ * Copyright 2012 GK Software AG
+ * 
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	  Stephan Herrmann - Initial API and implementation
+ * 
+ * This file is based on class org.apache.bcel.classfile.ConstantPool
+ * originating from the Apache BCEL project which was provided under the 
+ * Apache 2.0 license. Original Copyright from BCEL:
+ *
+ * Copyright  2000-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); 
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License. 
+ *
+ */
+package org.apache.bcel.generic;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.bcel.classfile.Utility;
+
+/**
+ * Instances of this class give users a handle to the instructions contained in
+ * an InstructionList. Instruction objects may be used more than once within a
+ * list, this is useful because it saves memory and may be much faster.
+ *
+ * Within an InstructionList an InstructionHandle object is wrapped
+ * around all instructions, i.e., it implements a cell in a
+ * doubly-linked list. From the outside only the next and the
+ * previous instruction (handle) are accessible. One
+ * can traverse the list via an Enumeration returned by
+ * InstructionList.elements().
+ *
+ * @version $Id: InstructionHandle.java 386056 2006-03-15 11:31:56Z tcurdt $
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see Instruction
+ * @see BranchHandle
+ * @see InstructionList 
+ */
+public class InstructionHandle implements java.io.Serializable {
+
+    InstructionHandle next, prev; // Will be set from the outside
+    Instruction instruction;
+    protected int i_position = -1; // byte code offset of instruction
+    private Set targeters;
+    private Map attributes;
+
+
+    public final InstructionHandle getNext() {
+        return next;
+    }
+
+
+    public final InstructionHandle getPrev() {
+        return prev;
+    }
+
+
+    public final Instruction getInstruction() {
+        return instruction;
+    }
+
+
+    /**
+     * Replace current instruction contained in this handle.
+     * Old instruction is disposed using Instruction.dispose().
+     */
+    public void setInstruction( Instruction i ) { // Overridden in BranchHandle
+        if (i == null) {
+            throw new ClassGenException("Assigning null to handle");
+        }
+        if ((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) {
+            throw new ClassGenException("Assigning branch instruction " + i + " to plain handle");
+        }
+        if (instruction != null) {
+            instruction.dispose();
+        }
+        instruction = i;
+    }
+
+
+    /**
+     * Temporarily swap the current instruction, without disturbing
+     * anything. Meant to be used by a debugger, implementing
+     * breakpoints. Current instruction is returned.
+     */
+    public Instruction swapInstruction( Instruction i ) {
+        Instruction oldInstruction = instruction;
+        instruction = i;
+        return oldInstruction;
+    }
+
+
+    /*private*/protected InstructionHandle(Instruction i) {
+        setInstruction(i);
+    }
+
+    private static InstructionHandle ih_list = null; // List of reusable handles
+
+
+    /** Factory method.
+     */
+    static final InstructionHandle getInstructionHandle( Instruction i ) {
+        if (ih_list == null) {
+            return new InstructionHandle(i);
+        } else {
+            InstructionHandle ih = ih_list;
+            ih_list = ih.next;
+            ih.setInstruction(i);
+            return ih;
+        }
+    }
+
+
+    /**
+     * Called by InstructionList.setPositions when setting the position for every
+     * instruction. In the presence of variable length instructions `setPositions()'
+     * performs multiple passes over the instruction list to calculate the
+     * correct (byte) positions and offsets by calling this function.
+     *
+     * @param offset additional offset caused by preceding (variable length) instructions
+     * @param max_offset the maximum offset that may be caused by these instructions
+     * @return additional offset caused by possible change of this instruction's length
+     */
+    protected int updatePosition( int offset, int max_offset ) {
+        i_position += offset;
+        return 0;
+    }
+
+
+    /** @return the position, i.e., the byte code offset of the contained
+     * instruction. This is accurate only after
+     * InstructionList.setPositions() has been called.
+     */
+    public int getPosition() {
+        return i_position;
+    }
+
+
+    /** Set the position, i.e., the byte code offset of the contained
+     * instruction.
+     */
+    void setPosition( int pos ) {
+        i_position = pos;
+    }
+
+
+    /** Overridden in BranchHandle
+     */
+    protected void addHandle() {
+        next = ih_list;
+        ih_list = this;
+    }
+
+
+    /**
+     * Delete contents, i.e., remove user access and make handle reusable.
+     */
+    void dispose() {
+        next = prev = null;
+        instruction.dispose();
+        instruction = null;
+        i_position = -1;
+        attributes = null;
+        removeAllTargeters();
+        addHandle();
+    }
+
+
+    /** Remove all targeters, if any.
+     */
+    public void removeAllTargeters() {
+        if (targeters != null) {
+            targeters.clear();
+        }
+    }
+
+
+    /**
+     * Denote this handle isn't referenced anymore by t.
+     */
+    public void removeTargeter( InstructionTargeter t ) {
+        if (targeters != null) {
+            targeters.remove(t);
+        }
+    }
+
+
+    /**
+     * Denote this handle is being referenced by t.
+     */
+    public void addTargeter( InstructionTargeter t ) {
+        if (targeters == null) {
+            targeters = new HashSet();
+        }
+        //if(!targeters.contains(t))
+        targeters.add(t);
+    }
+
+
+    public boolean hasTargeters() {
+        return (targeters != null) && (targeters.size() > 0);
+    }
+
+
+    /**
+     * @return null, if there are no targeters
+     */
+    public InstructionTargeter[] getTargeters() {
+        if (!hasTargeters()) {
+            return null;
+        }
+        InstructionTargeter[] t = new InstructionTargeter[targeters.size()];
+        targeters.toArray(t);
+        return t;
+    }
+
+
+    /** @return a (verbose) string representation of the contained instruction. 
+     */
+    public String toString( boolean verbose ) {
+        return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose);
+    }
+
+
+    /** @return a string representation of the contained instruction. 
+     */
+    public String toString() {
+        return toString(true);
+    }
+
+
+    /** Add an attribute to an instruction handle.
+     *
+     * @param key the key object to store/retrieve the attribute
+     * @param attr the attribute to associate with this handle
+     */
+    public void addAttribute( Object key, Object attr ) {
+        if (attributes == null) {
+            attributes = new HashMap(3);
+        }
+        attributes.put(key, attr);
+    }
+
+
+    /** Delete an attribute of an instruction handle.
+     *
+     * @param key the key object to retrieve the attribute
+     */
+    public void removeAttribute( Object key ) {
+        if (attributes != null) {
+            attributes.remove(key);
+        }
+    }
+
+
+    /** Get attribute of an instruction handle.
+     *
+     * @param key the key object to store/retrieve the attribute
+     */
+    public Object getAttribute( Object key ) {
+        if (attributes != null) {
+            return attributes.get(key);
+        }
+        return null;
+    }
+
+
+    /** @return all attributes associated with this handle
+     */
+    public Collection getAttributes() {
+        if (attributes == null) {
+            attributes = new HashMap(3);
+        }
+        return attributes.values();
+    }
+
+
+    /** Convenience method, simply calls accept() on the contained instruction.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        instruction.accept(v);
+    }
+}