Instantiation(final Instantiation prev, final Subroutine sub) {
			previous = prev;
			subroutine = sub;
			for (Instantiation p = prev; p != null; p = p.previous) {
				if (p.subroutine == sub) {
					throw new RuntimeException("Recursive invocation of " + sub);
				}
			}

			// Determine the label to return to when this subroutine terminates
			// via RET: note that the main subroutine never terminates via RET.
			if (prev != null) {
				returnLabel = new LabelNode();
			} else {
				returnLabel = null;
			}

			// Each instantiation will remap the labels from the code above to
			// refer to its particular copy of its own instructions. Note that
			// we collapse labels which point at the same instruction into one:
			// this is fairly common as we are often ignoring large chunks of
			// instructions, so what were previously distinct labels become
			// duplicates.
			LabelNode duplbl = null;
			for (int i = 0, c = instructions.size(); i < c; i++) {
				AbstractInsnNode insn = instructions.get(i);

				if (insn.getType() == AbstractInsnNode.LABEL) {
					LabelNode ilbl = (LabelNode) insn;

					if (duplbl == null) {
						// if we already have a label pointing at this spot,
						// don't recreate it.
						duplbl = new LabelNode();
					}

					// Add an entry in the rangeTable for every label
					// in the original code which points at the next
					// instruction of our own to be emitted.
					rangeTable.put(ilbl, duplbl);
				} else if (findOwner(i) == this) {
					// We will emit this instruction, so clear the 'duplbl' flag
					// since the next Label will refer to a distinct
					// instruction.
					duplbl = null;
				}
			}
		}