private int replace(ConstPool cp, CodeIterator iterator, int pos,
            int opcode, String signature) throws BadBytecode {
        String castType = null;
        String methodName = getMethodName(opcode);
        if (methodName != null) {
            // See if the object must be cast
            if (opcode == AALOAD) {
                castType = getTopType(iterator.lookAhead());
                // Do not replace an AALOAD instruction that we do not have a type for
                // This happens when the state is guaranteed to be null (Type.UNINIT)
                // So we don't really care about this case.
                if (castType == null)
                    return pos;
                if ("java/lang/Object".equals(castType))
                    castType = null;
            }

            // The gap may include extra padding
            // Write a nop in case the padding pushes the instruction forward
            iterator.writeByte(NOP, pos);
            CodeIterator.Gap gap
                = iterator.insertGapAt(pos, castType != null ? 5 : 2, false);
            pos = gap.position;
            int mi = cp.addClassInfo(methodClassname);
            int methodref = cp.addMethodrefInfo(mi, methodName, signature);
            iterator.writeByte(INVOKESTATIC, pos);
            iterator.write16bit(methodref, pos + 1);

            if (castType != null) {
                int index = cp.addClassInfo(castType);
                iterator.writeByte(CHECKCAST, pos + 3);
                iterator.write16bit(index, pos + 4);
            }

            pos = updatePos(pos, gap.length);
        }

        return pos;
    }