static MethodHandle makeCollectArguments(MethodHandle target,MethodHandle collector,int collectArgPos,boolean retainOriginalArgs){
  MethodType targetType=target.type();
  MethodType collectorType=collector.type();
  int collectArgCount=collectorType.parameterCount();
  Class<?> collectValType=collectorType.returnType();
  int collectValCount=(collectValType == void.class ? 0 : 1);
  MethodType srcType=targetType.dropParameterTypes(collectArgPos,collectArgPos + collectValCount);
  if (!retainOriginalArgs) {
    srcType=srcType.insertParameterTypes(collectArgPos,collectorType.parameterList());
  }
  MethodType lambdaType=srcType.invokerType();
  Name[] names=arguments(2,lambdaType);
  final int collectNamePos=names.length - 2;
  final int targetNamePos=names.length - 1;
  Name[] collectorArgs=Arrays.copyOfRange(names,1 + collectArgPos,1 + collectArgPos + collectArgCount);
  names[collectNamePos]=new Name(collector,(Object[])collectorArgs);
  Name[] targetArgs=new Name[targetType.parameterCount()];
  int inputArgPos=1;
  int targetArgPos=0;
  int chunk=collectArgPos;
  System.arraycopy(names,inputArgPos,targetArgs,targetArgPos,chunk);
  inputArgPos+=chunk;
  targetArgPos+=chunk;
  if (collectValType != void.class) {
    targetArgs[targetArgPos++]=names[collectNamePos];
  }
  chunk=collectArgCount;
  if (retainOriginalArgs) {
    System.arraycopy(names,inputArgPos,targetArgs,targetArgPos,chunk);
    targetArgPos+=chunk;
  }
  inputArgPos+=chunk;
  chunk=targetArgs.length - targetArgPos;
  System.arraycopy(names,inputArgPos,targetArgs,targetArgPos,chunk);
  assert (inputArgPos + chunk == collectNamePos);
  names[targetNamePos]=new Name(target,(Object[])targetArgs);
  LambdaForm form=new LambdaForm("collect",lambdaType.parameterCount(),names);
  return SimpleMethodHandle.make(srcType,form);
}

static MethodHandle makeCollectArguments ( MethodHandle target , MethodHandle collector , int collectArgPos , boolean retainOriginalArgs ) { MethodType targetType = target . type ( ) ; MethodType collectorType = collector . type ( ) ; int collectArgCount = collectorType . parameterCount ( ) ; Class < ? > collectValType = collectorType . returnType ( ) ; int collectValCount = ( collectValType == void . class ? 0 : 1 ) ; MethodType srcType = targetType . dropParameterTypes ( collectArgPos , collectArgPos + collectValCount ) ; if ( ! retainOriginalArgs ) { srcType = srcType . insertParameterTypes ( collectArgPos , collectorType . parameterList ( ) ) ; } MethodType lambdaType = srcType . invokerType ( ) ; Name [ ] names = arguments ( 2 , lambdaType ) ; final int collectNamePos = names . length - 2 ; final int targetNamePos = names . length - 1 ; Name [ ] collectorArgs = Arrays . copyOfRange ( names , 1 + collectArgPos , 1 + collectArgPos + collectArgCount ) ; names [ collectNamePos ] = new Name ( collector , ( Object [ ] ) collectorArgs ) ; Name [ ] targetArgs = new Name [ targetType . parameterCount ( ) ] ; int inputArgPos = 1 ; int targetArgPos = 0 ; int chunk = collectArgPos ; System . arraycopy ( names , inputArgPos , targetArgs , targetArgPos , chunk ) ; inputArgPos += chunk ; targetArgPos += chunk ; if ( collectValType != void . class ) { targetArgs [ targetArgPos ++ ] = names [ collectNamePos ] ; } chunk = collectArgCount ; if ( retainOriginalArgs ) { System . arraycopy ( names , inputArgPos , targetArgs , targetArgPos , chunk ) ; targetArgPos += chunk ; } inputArgPos += chunk ; chunk = targetArgs . length - targetArgPos ; System . arraycopy ( names , inputArgPos , targetArgs , targetArgPos , chunk ) ; assert ( inputArgPos + chunk == collectNamePos ) ; names [ targetNamePos ] = new Name ( target , ( Object [ ] ) targetArgs ) ; LambdaForm form = new LambdaForm ( "collect" , lambdaType . parameterCount ( ) , names ) ; return SimpleMethodHandle . make ( srcType , form ) ; }
factory method : collect or filter selected argument ( s ) .
