cglib/src/main/java/net/sf/cglib/core/EmitUtils.java
public static void wrap_undeclared_throwable(CodeEmitter e, Block handler, Type[] exceptions, Type wrapper) {
        Set set = (exceptions == null) ? Collections.EMPTY_SET : new HashSet(Arrays.asList(exceptions));

        if (set.contains(Constants.TYPE_THROWABLE))
            return;

        boolean needThrow = exceptions != null;
        if (!set.contains(Constants.TYPE_RUNTIME_EXCEPTION)) {
            e.catch_exception(handler, Constants.TYPE_RUNTIME_EXCEPTION);
            needThrow = true;
        }
        if (!set.contains(Constants.TYPE_ERROR)) {
            e.catch_exception(handler, Constants.TYPE_ERROR);
            needThrow = true;
        }
        if (exceptions != null) {
            for (int i = 0; i < exceptions.length; i++) {
                e.catch_exception(handler, exceptions[i]);
            }
        }
        if (needThrow) {
            e.athrow();
        }
        // e -> eo -> oeo -> ooe -> o
        e.catch_exception(handler, Constants.TYPE_THROWABLE);
        e.new_instance(wrapper);
        e.dup_x1();
        e.swap();
        e.invoke_constructor(wrapper, CSTRUCT_THROWABLE);
        e.athrow();
    }
public static void wrap_undeclared_throwable(CodeEmitter e, Block handler, Type[] exceptions, Type wrapper) {
        Set set = (exceptions == null) ? Collections.EMPTY_SET : new HashSet(Arrays.asList(exceptions));

        if (set.contains(Constants.TYPE_THROWABLE))
            return;

        boolean needThrow = exceptions != null;
        if (!set.contains(Constants.TYPE_RUNTIME_EXCEPTION)) {
            e.catch_exception(handler, Constants.TYPE_RUNTIME_EXCEPTION);
            needThrow = true;
        }
        if (!set.contains(Constants.TYPE_ERROR)) {
            e.catch_exception(handler, Constants.TYPE_ERROR);
            needThrow = true;
        }
        if (exceptions != null) {
            for (int i = 0; i < exceptions.length; i++) {
                e.catch_exception(handler, exceptions[i]);
            }
        }
        if (needThrow) {
            e.athrow();
        }
        // e -> eo -> oeo -> ooe -> o
        e.catch_exception(handler, Constants.TYPE_THROWABLE);
        e.new_instance(wrapper);
        e.dup_x1();
        e.swap();
        e.invoke_constructor(wrapper, CSTRUCT_THROWABLE);
        e.athrow();
    }
/* generates:
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (<DeclaredException> e) {
throw e;
} catch (Throwable e) {
throw new <Wrapper>(e);
}