// Factory methods:
        internal static DirectMethodHandle Make(sbyte refKind, Class receiver, MemberName member)
        {
            MethodType mtype = member.MethodOrFieldType;

            if (!member.Static)
            {
                if (!receiver.IsSubclassOf(member.DeclaringClass) || member.Constructor)
                {
                    throw new InternalError(member.ToString());
                }
                mtype = mtype.InsertParameterTypes(0, receiver);
            }
            if (!member.Field)
            {
                if (refKind == REF_invokeSpecial)
                {
                    member = member.AsSpecial();
                    LambdaForm lform = PreparedLambdaForm(member);
                    return(new Special(mtype, lform, member));
                }
                else
                {
                    LambdaForm lform = PreparedLambdaForm(member);
                    return(new DirectMethodHandle(mtype, lform, member));
                }
            }
            else
            {
                LambdaForm lform = PreparedFieldLambdaForm(member);
                if (member.Static)
                {
                    long   offset = MethodHandleNatives.staticFieldOffset(member);
                    Object @base  = MethodHandleNatives.staticFieldBase(member);
                    return(new StaticAccessor(mtype, lform, member, @base, offset));
                }
                else
                {
                    long offset = MethodHandleNatives.objectFieldOffset(member);
                    assert(offset == (int)offset);
                    return(new Accessor(mtype, lform, member, (int)offset));
                }
            }
        }
        private static LambdaForm MakePreparedLambdaForm(MethodType mtype, int which)
        {
            bool   needsInit = (which == LF_INVSTATIC_INIT);
            bool   doesAlloc = (which == LF_NEWINVSPECIAL);
            String linkerName, lambdaName;

            switch (which)
            {
            case LF_INVVIRTUAL:
                linkerName = "linkToVirtual";
                lambdaName = "DMH.invokeVirtual";
                break;

            case LF_INVSTATIC:
                linkerName = "linkToStatic";
                lambdaName = "DMH.invokeStatic";
                break;

            case LF_INVSTATIC_INIT:
                linkerName = "linkToStatic";
                lambdaName = "DMH.invokeStaticInit";
                break;

            case LF_INVSPECIAL:
                linkerName = "linkToSpecial";
                lambdaName = "DMH.invokeSpecial";
                break;

            case LF_INVINTERFACE:
                linkerName = "linkToInterface";
                lambdaName = "DMH.invokeInterface";
                break;

            case LF_NEWINVSPECIAL:
                linkerName = "linkToSpecial";
                lambdaName = "DMH.newInvokeSpecial";
                break;

            default:
                throw new InternalError("which=" + which);
            }
            MethodType mtypeWithArg = mtype.AppendParameterTypes(typeof(MemberName));

            if (doesAlloc)
            {
                mtypeWithArg = mtypeWithArg.InsertParameterTypes(0, typeof(Object)).ChangeReturnType(typeof(void));                 // <init> returns void -  insert newly allocated obj
            }
            MemberName linker = new MemberName(typeof(MethodHandle), linkerName, mtypeWithArg, REF_invokeStatic);

            try
            {
                linker = IMPL_NAMES.ResolveOrFail(REF_invokeStatic, linker, null, typeof(NoSuchMethodException));
            }
            catch (ReflectiveOperationException ex)
            {
                throw newInternalError(ex);
            }
            const int DMH_THIS = 0;
            const int ARG_BASE = 1;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
            int ARG_LIMIT  = ARG_BASE + mtype.ParameterCount();
            int nameCursor = ARG_LIMIT;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1);
            int NEW_OBJ = (doesAlloc ? nameCursor++: -1);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int GET_MEMBER = nameCursor++;
            int GET_MEMBER = nameCursor++;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int LINKER_CALL = nameCursor++;
            int LINKER_CALL = nameCursor++;

            Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.InvokerType());
            assert(names.Length == nameCursor);
            if (doesAlloc)
            {
                // names = { argx,y,z,... new C, init method }
                names[NEW_OBJ]    = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
                names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
            }
            else if (needsInit)
            {
                names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
            }
            else
            {
                names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
            }
            assert(FindDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
            Object[] outArgs = Arrays.CopyOfRange(names, ARG_BASE, GET_MEMBER + 1, typeof(Object[]));
            assert(outArgs[outArgs.Length - 1] == names[GET_MEMBER]);             // look, shifted args!
            int result = LAST_RESULT;

            if (doesAlloc)
            {
                assert(outArgs[outArgs.Length - 2] == names[NEW_OBJ]);                 // got to move this one
                System.Array.Copy(outArgs, 0, outArgs, 1, outArgs.Length - 2);
                outArgs[0] = names[NEW_OBJ];
                result     = NEW_OBJ;
            }
            names[LINKER_CALL] = new Name(linker, outArgs);
            lambdaName        += "_" + shortenSignature(basicTypeSignature(mtype));
            LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);

            // This is a tricky bit of code.  Don't send it through the LF interpreter.
            lform.CompileToBytecode();
            return(lform);
        }