@Override
public ValueEmitter substitute(DynamicCallSite callSite, ProgramEmitter callerPe) {
ValueType[] invokedType = callSite.getCalledMethod().getSignature();
ValueType[] samMethodType = callSite.getBootstrapArguments().get(0).getMethodType();
MethodHandle implMethod = callSite.getBootstrapArguments().get(1).getMethodHandle();
ValueType[] instantiatedMethodType = callSite.getBootstrapArguments().get(2).getMethodType();
String samName = ((ValueType.Object) callSite.getCalledMethod().getResultType()).getClassName();
ClassHierarchy hierarchy = callSite.getAgent().getClassHierarchy();
ClassReader samClass = hierarchy.getClassSource().get(samName);
int capturedVarCount = callSite.getCalledMethod().parameterCount();
MethodHolder ctor = createConstructor(hierarchy, implementor,
Arrays.copyOfRange(invokedType, 0, capturedVarCount), callerPe.getCurrentLocation());
createBridge(hierarchy, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType,
samMethodType, callerPe.getCurrentLocation());
MethodHolder worker = new MethodHolder(callSite.getCalledMethod().getName(), instantiatedMethodType);
worker.setLevel(AccessLevel.PUBLIC);
ProgramEmitter pe = ProgramEmitter.create(worker, callSite.getAgent().getClassHierarchy());
for (int i = 0; i < bridgeCount; ++i) {
ValueType[] bridgeType = callSite.getBootstrapArguments().get(bootstrapArgIndex++).getMethodType();
createBridge(hierarchy, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType,
bridgeType, callerPe.getCurrentLocation());