private LambdaForm MakeArgumentCombinationForm(int pos, MethodType combinerType, bool keepArguments, bool dropResult)
        {
            LambdaFormBuffer buf = Buffer();

            buf.StartEdit();
            int combinerArity = combinerType.ParameterCount();
            int resultArity   = (dropResult ? 0 : 1);

            assert(pos <= MethodType.MAX_JVM_ARITY);
            assert(pos + resultArity + (keepArguments ? combinerArity : 0) <= LambdaForm.Arity_Renamed);
            assert(pos > 0);             // cannot filter the MH arg itself
            assert(combinerType == combinerType.BasicType());
            assert(combinerType.ReturnType() != typeof(void) || dropResult);

            BoundMethodHandle.SpeciesData oldData = OldSpeciesData();
            BoundMethodHandle.SpeciesData newData = NewSpeciesData(L_TYPE);

            // The newly created LF will run with a different BMH.
            // Switch over any pre-existing BMH field references to the new BMH class.
            Name oldBaseAddress = LambdaForm.Parameter(0);             // BMH holding the values

            buf.ReplaceFunctions(oldData.GetterFunctions(), newData.GetterFunctions(), oldBaseAddress);
            Name newBaseAddress = oldBaseAddress.withConstraint(newData);

            buf.RenameParameter(0, newBaseAddress);

            Name getCombiner = new Name(newData.GetterFunction(oldData.FieldCount()), newBaseAddress);

            Object[] combinerArgs = new Object[1 + combinerArity];
            combinerArgs[0] = getCombiner;
            Name[] newParams;
            if (keepArguments)
            {
                newParams = new Name[0];
                System.Array.Copy(LambdaForm.Names, pos + resultArity, combinerArgs, 1, combinerArity);
            }
            else
            {
                newParams = new Name[combinerArity];
                BasicType[] newTypes = basicTypes(combinerType.ParameterList());
                for (int i = 0; i < newTypes.Length; i++)
                {
                    newParams[i] = new Name(pos + i, newTypes[i]);
                }
                System.Array.Copy(newParams, 0, combinerArgs, 1, combinerArity);
            }
            Name callCombiner = new Name(combinerType, combinerArgs);

            // insert the two new expressions
            int exprPos = LambdaForm.Arity();

            buf.InsertExpression(exprPos + 0, getCombiner);
            buf.InsertExpression(exprPos + 1, callCombiner);

            // insert new arguments, if needed
            int argPos = pos + resultArity;             // skip result parameter

            foreach (Name newParam in newParams)
            {
                buf.InsertParameter(argPos++, newParam);
            }
            assert(buf.LastIndexOf(callCombiner) == exprPos + 1 + newParams.Length);
            if (!dropResult)
            {
                buf.ReplaceParameterByCopy(pos, exprPos + 1 + newParams.Length);
            }

            return(buf.EndEdit());
        }