Fixed bug #316553.
diff --git a/src/org/objectweb/asm/tree/InsnList.java b/src/org/objectweb/asm/tree/InsnList.java
index c260101..191ad0f 100644
--- a/src/org/objectweb/asm/tree/InsnList.java
+++ b/src/org/objectweb/asm/tree/InsnList.java
@@ -527,6 +527,8 @@
 
         AbstractInsnNode prev;
 
+        AbstractInsnNode remove;
+
         InsnListIterator(int index) {
             if (index == size()) {
                 next = null;
@@ -548,12 +550,22 @@
             AbstractInsnNode result = next;
             prev = result;
             next = result.next;
+            remove = result;
             return result;
         }
 
         public void remove() {
-            InsnList.this.remove(prev);
-            prev = prev.prev;
+            if (remove != null) {
+                if (remove == next) {
+                    next = next.next;
+                } else {
+                    prev = prev.prev;
+                }
+                InsnList.this.remove(remove);
+                remove = null;
+            } else {
+                throw new IllegalStateException();
+            }
         }
 
         public boolean hasPrevious() {
@@ -564,6 +576,7 @@
             AbstractInsnNode result = prev;
             next = result;
             prev = result.prev;
+            remove = result;
             return result;
         }
 
@@ -590,6 +603,7 @@
         public void add(Object o) {
             InsnList.this.insertBefore(next, (AbstractInsnNode) o);
             prev = (AbstractInsnNode) o;
+            remove = null;
         }
 
         public void set(Object o) {
diff --git a/test/conform/org/objectweb/asm/tree/InsnListUnitTest.java b/test/conform/org/objectweb/asm/tree/InsnListUnitTest.java
index 6e87a83..f8ca568 100644
--- a/test/conform/org/objectweb/asm/tree/InsnListUnitTest.java
+++ b/test/conform/org/objectweb/asm/tree/InsnListUnitTest.java
@@ -123,6 +123,7 @@
         assertEquals(in2, it.next());
         assertTrue(it.hasNext());
         it.remove(); // remove in2
+        assertTrue(it.hasPrevious());
         assertTrue(it.hasNext());
         assertEquals(insn, it.next());
         assertFalse(it.hasNext());
@@ -210,6 +211,38 @@
     }
 
     public void testIterator3() {
+        InsnNode insn = new InsnNode(0);
+        l2.add(insn);
+
+        // reverse iteration
+        ListIterator<AbstractInsnNode> it = l2.iterator(3);
+        assertFalse(it.hasNext());
+        assertTrue(it.hasPrevious());
+        assertEquals(insn, it.previous());
+        assertTrue(it.hasPrevious());
+        assertEquals(in2, it.previous());
+        assertTrue(it.hasPrevious());
+        assertEquals(in1, it.previous());
+        assertFalse(it.hasPrevious());
+
+        // reverse iteration with remove()
+        it = l2.iterator(3);
+        assertFalse(it.hasNext());
+        assertTrue(it.hasPrevious());
+        assertEquals(insn, it.previous());
+        it.remove(); // remove insn
+        assertTrue(it.hasPrevious());
+        assertEquals(in2, it.previous());
+        it.remove(); // remove in2
+        assertTrue(it.hasPrevious());
+        assertEquals(in1, it.previous());
+        assertFalse(it.hasPrevious());
+
+        assertEquals(1, l2.size());
+        assertEquals(in1, l2.getFirst());
+    }
+
+    public void testIterator4() {
         try {
             new InsnList().iterator().next();
             fail();