diff --git a/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
index f27d66aed2c..abbab3d7753 100644
--- a/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,8 @@ package java.lang.invoke;
 
 import java.io.Serializable;
 import java.util.Arrays;
+import java.lang.reflect.Array;
+import java.util.Objects;
 
 /**
  * <p>Methods to facilitate the creation of simple "function objects" that
@@ -39,41 +41,47 @@ import java.util.Arrays;
  * <p>Indirect access to the behavior specified by the provided {@code MethodHandle}
  * proceeds in order through three phases:
  * <ul>
- *     <li><em>Linkage</em> occurs when the methods in this class are invoked.
+ *     <li><p><em>Linkage</em> occurs when the methods in this class are invoked.
  *     They take as arguments an interface to be implemented (typically a
  *     <em>functional interface</em>, one with a single abstract method), a
  *     name and signature of a method from that interface to be implemented, a
- *     method handle describing the desired implementation behavior
- *     for that method, and possibly other additional metadata, and produce a
- *     {@link CallSite} whose target can be used to create suitable function
- *     objects.  Linkage may involve dynamically loading a new class that
- *     implements the target interface. The {@code CallSite} can be considered a
- *     "factory" for function objects and so these linkage methods are referred
- *     to as "metafactories".</li>
+ *     {@linkplain MethodHandleInfo direct method handle} describing the desired
+ *     implementation behavior for that method, and possibly other additional
+ *     metadata, and produce a {@link CallSite} whose target can be used to
+ *     create suitable function objects.
  *
- *     <li><em>Capture</em> occurs when the {@code CallSite}'s target is
+ *     <p>Linkage may involve dynamically loading a new class that implements
+ *     the target interface, or re-using a suitable existing class.
+ *
+ *     <p>The {@code CallSite} can be considered a "factory" for function
+ *     objects and so these linkage methods are referred to as
+ *     "metafactories".</li>
+ *
+ *     <li><p><em>Capture</em> occurs when the {@code CallSite}'s target is
  *     invoked, typically through an {@code invokedynamic} call site,
- *     producing a function object.  This may occur many times for
- *     a single factory {@code CallSite}.  Capture may involve allocation of a
- *     new function object, or may return an existing function object.  The
- *     behavior {@code MethodHandle} may have additional parameters beyond those
- *     of the specified interface method; these are referred to as <em>captured
- *     parameters</em>, which must be provided as arguments to the
- *     {@code CallSite} target, and which may be early-bound to the behavior
- *     {@code MethodHandle}.  The number of captured parameters and their types
- *     are determined during linkage.
- *     The identity of a function object produced by invoking the
- *     {@code CallSite}'s target is unpredictable, and therefore
- *     identity-sensitive operations (such as reference equality, object
- *     locking, and {@code System.identityHashCode()} may produce different
- *     results in different implementations, or even upon different invocations
- *     in the same implementation.</li>
+ *     producing a function object. This may occur many times for
+ *     a single factory {@code CallSite}.
+ *
+ *     <p>If the behavior {@code MethodHandle} has additional parameters beyond
+ *     those of the specified interface method, these are referred to as
+ *     <em>captured parameters</em>, which must be provided as arguments to the
+ *     {@code CallSite} target. The expected number and types of captured
+ *     parameters are determined during linkage.
  *
- *     <li><em>Invocation</em> occurs when an implemented interface method
- *     is invoked on a function object.  This may occur many times for a single
- *     function object.  The method referenced by the behavior {@code MethodHandle}
- *     is invoked with the captured arguments and any additional arguments
- *     provided on invocation, as if by {@link MethodHandle#invoke(Object...)}.</li>
+ *     <p>Capture may involve allocation of a new function object, or may return
+ *     a suitable existing function object. The identity of a function object
+ *     produced by capture is unpredictable, and therefore identity-sensitive
+ *     operations (such as reference equality, object locking, and {@code
+ *     System.identityHashCode()}) may produce different results in different
+ *     implementations, or even upon different invocations in the same
+ *     implementation.</li>
+ *
+ *     <li><p><em>Invocation</em> occurs when an implemented interface method is
+ *     invoked on a function object. This may occur many times for a single
+ *     function object. The method referenced by the implementation
+ *     {@code MethodHandle} is invoked, passing to it the captured arguments and
+ *     the invocation arguments. The result of the method is returned.
+ *     </li>
  * </ul>
  *
  * <p>It is sometimes useful to restrict the set of inputs or results permitted
@@ -81,7 +89,7 @@ import java.util.Arrays;
  * is parameterized as {@code Predicate<String>}, the input must be a
  * {@code String}, even though the method to implement allows any {@code Object}.
  * At linkage time, an additional {@link MethodType} parameter describes the
- * "instantiated" method type; on invocation, the arguments and eventual result
+ * "dynamic" method type; on invocation, the arguments and eventual result
  * are checked against this {@code MethodType}.
  *
  * <p>This class provides two forms of linkage methods: a standard version
@@ -94,7 +102,7 @@ import java.util.Arrays;
  * manage the following attributes of function objects:
  *
  * <ul>
- *     <li><em>Bridging.</em>  It is sometimes useful to implement multiple
+ *     <li><em>Multiple methods.</em>  It is sometimes useful to implement multiple
  *     variations of the method signature, involving argument or return type
  *     adaptation.  This occurs when multiple distinct VM signatures for a method
  *     are logically considered to be the same method by the language.  The
@@ -121,24 +129,22 @@ import java.util.Arrays;
  *
  * <p>Assume the linkage arguments are as follows:
  * <ul>
- *      <li>{@code invokedType} (describing the {@code CallSite} signature) has
+ *      <li>{@code factoryType} (describing the {@code CallSite} signature) has
  *      K parameters of types (D1..Dk) and return type Rd;</li>
- *      <li>{@code samMethodType} (describing the implemented method type) has N
+ *      <li>{@code interfaceMethodType} (describing the implemented method type) has N
  *      parameters, of types (U1..Un) and return type Ru;</li>
- *      <li>{@code implMethod} (the {@code MethodHandle} providing the
- *      implementation has M parameters, of types (A1..Am) and return type Ra
+ *      <li>{@code implementation} (the {@code MethodHandle} providing the
+ *      implementation) has M parameters, of types (A1..Am) and return type Ra
  *      (if the method describes an instance method, the method type of this
  *      method handle already includes an extra first argument corresponding to
  *      the receiver);</li>
- *      <li>{@code instantiatedMethodType} (allowing restrictions on invocation)
+ *      <li>{@code dynamicMethodType} (allowing restrictions on invocation)
  *      has N parameters, of types (T1..Tn) and return type Rt.</li>
  * </ul>
  *
  * <p>Then the following linkage invariants must hold:
  * <ul>
- *     <li>Rd is an interface</li>
- *     <li>{@code implMethod} is a <em>direct method handle</em></li>
- *     <li>{@code samMethodType} and {@code instantiatedMethodType} have the same
+ *     <li>{@code interfaceMethodType} and {@code dynamicMethodType} have the same
  *     arity N, and for i=1..N, Ti and Ui are the same type, or Ti and Ui are
  *     both reference types and Ti is a subtype of Ui</li>
  *     <li>Either Rt and Ru are the same type, or both are reference types and
@@ -150,7 +156,7 @@ import java.util.Arrays;
  *     adaptable to Rt</li>
  * </ul>
  *
- * <p>Further, at capture time, if {@code implMethod} corresponds to an instance
+ * <p>Further, at capture time, if {@code implementation} corresponds to an instance
  * method, and there are any capture arguments ({@code K > 0}), then the first
  * capture argument (corresponding to the receiver) must be non-null.
  *
@@ -218,30 +224,30 @@ import java.util.Arrays;
  * method signature describing the number and static types (but not the values)
  * of the dynamic arguments and the static return type of the invokedynamic site.
  *
- * @implNote The implementation method is described with a method handle. In
- * theory, any method handle could be used. Currently supported are direct method
- * handles representing invocation of virtual, interface, constructor and static
- * methods.
+ * <p>The implementation method is described with a direct method handle
+ * referencing a method or constructor. In theory, any method handle could be
+ * used, but this is not compatible with some implementation techniques and
+ * would complicate the work implementations must do.
+ *
  * @since 1.8
  */
 public final class LambdaMetafactory {
 
     private LambdaMetafactory() {}
 
-    /** Flag for alternate metafactories indicating the lambda object
+    /** Flag for {@link #altMetafactory} indicating the lambda object
      * must be serializable */
     public static final int FLAG_SERIALIZABLE = 1 << 0;
 
     /**
-     * Flag for alternate metafactories indicating the lambda object implements
-     * other marker interfaces
-     * besides Serializable
+     * Flag for {@link #altMetafactory} indicating the lambda object implements
+     * other interfaces besides {@code Serializable}
      */
     public static final int FLAG_MARKERS = 1 << 1;
 
     /**
      * Flag for alternate metafactories indicating the lambda object requires
-     * additional bridge methods
+     * additional methods that invoke the {@code implementation}
      */
     public static final int FLAG_BRIDGES = 1 << 2;
 
@@ -249,7 +255,7 @@ public final class LambdaMetafactory {
     private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
 
     // LambdaMetafactory bootstrap methods are startup sensitive, and may be
-    // special cased in java.lang.invokeBootstrapMethodInvoker to ensure
+    // special cased in java.lang.invoke.BootstrapMethodInvoker to ensure
     // methods are invoked with exact type information to avoid generating
     // code for runtime checks. Take care any changes or additions here are
     // reflected there as appropriate.
@@ -269,9 +275,9 @@ public final class LambdaMetafactory {
      *
      * <p>When the target of the {@code CallSite} returned from this method is
      * invoked, the resulting function objects are instances of a class which
-     * implements the interface named by the return type of {@code invokedType},
-     * declares a method with the name given by {@code invokedName} and the
-     * signature given by {@code samMethodType}.  It may also override additional
+     * implements the interface named by the return type of {@code factoryType},
+     * declares a method with the name given by {@code interfaceMethodName} and the
+     * signature given by {@code interfaceMethodType}.  It may also override additional
      * methods from {@code Object}.
      *
      * @param caller Represents a lookup context with the accessibility
@@ -280,50 +286,57 @@ public final class LambdaMetafactory {
      *               full privilege access}.
      *               When used with {@code invokedynamic}, this is stacked
      *               automatically by the VM.
-     * @param invokedName The name of the method to implement.  When used with
-     *                    {@code invokedynamic}, this is provided by the
-     *                    {@code NameAndType} of the {@code InvokeDynamic}
-     *                    structure and is stacked automatically by the VM.
-     * @param invokedType The expected signature of the {@code CallSite}.  The
+     * @param interfaceMethodName The name of the method to implement.  When used with
+     *                            {@code invokedynamic}, this is provided by the
+     *                            {@code NameAndType} of the {@code InvokeDynamic}
+     *                            structure and is stacked automatically by the VM.
+     * @param factoryType The expected signature of the {@code CallSite}.  The
      *                    parameter types represent the types of capture variables;
      *                    the return type is the interface to implement.   When
      *                    used with {@code invokedynamic}, this is provided by
      *                    the {@code NameAndType} of the {@code InvokeDynamic}
      *                    structure and is stacked automatically by the VM.
-     *                    In the event that the implementation method is an
-     *                    instance method and this signature has any parameters,
-     *                    the first parameter in the invocation signature must
-     *                    correspond to the receiver.
-     * @param samMethodType Signature and return type of method to be implemented
-     *                      by the function object.
-     * @param implMethod A direct method handle describing the implementation
-     *                   method which should be called (with suitable adaptation
-     *                   of argument types, return types, and with captured
-     *                   arguments prepended to the invocation arguments) at
-     *                   invocation time.
-     * @param instantiatedMethodType The signature and return type that should
-     *                               be enforced dynamically at invocation time.
-     *                               This may be the same as {@code samMethodType},
-     *                               or may be a specialization of it.
+     * @param interfaceMethodType Signature and return type of method to be
+     *                            implemented by the function object.
+     * @param implementation A direct method handle describing the implementation
+     *                       method which should be called (with suitable adaptation
+     *                       of argument types and return types, and with captured
+     *                       arguments prepended to the invocation arguments) at
+     *                       invocation time.
+     * @param dynamicMethodType The signature and return type that should
+     *                          be enforced dynamically at invocation time.
+     *                          In simple use cases this is the same as
+     *                          {@code interfaceMethodType}.
      * @return a CallSite whose target can be used to perform capture, generating
-     *         instances of the interface named by {@code invokedType}
-     * @throws LambdaConversionException If any of the linkage invariants
-     *                                   described {@link LambdaMetafactory above}
-     *                                   are violated, or the lookup context
-     *                                   does not have private access privileges.
+     *         instances of the interface named by {@code factoryType}
+     * @throws LambdaConversionException If {@code caller} does not have full privilege
+     *         access, or if {@code interfaceMethodName} is not a valid JVM
+     *         method name, or if the return type of {@code factoryType} is not
+     *         an interface, or if {@code implementation} is not a direct method
+     *         handle referencing a method or constructor, or if the linkage
+     *         invariants are violated, as defined {@link LambdaMetafactory above}.
+     * @throws NullPointerException If any argument is {@code null}.
+     * @throws SecurityException If a security manager is present, and it
+     *         <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+     *         from {@code caller} to the package of {@code implementation}.
      */
     public static CallSite metafactory(MethodHandles.Lookup caller,
-                                       String invokedName,
-                                       MethodType invokedType,
-                                       MethodType samMethodType,
-                                       MethodHandle implMethod,
-                                       MethodType instantiatedMethodType)
+                                       String interfaceMethodName,
+                                       MethodType factoryType,
+                                       MethodType interfaceMethodType,
+                                       MethodHandle implementation,
+                                       MethodType dynamicMethodType)
             throws LambdaConversionException {
         AbstractValidatingLambdaMetafactory mf;
-        mf = new InnerClassLambdaMetafactory(caller, invokedType,
-                                             invokedName, samMethodType,
-                                             implMethod, instantiatedMethodType,
-                                             false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
+        mf = new InnerClassLambdaMetafactory(Objects.requireNonNull(caller),
+                                             Objects.requireNonNull(factoryType),
+                                             Objects.requireNonNull(interfaceMethodName),
+                                             Objects.requireNonNull(interfaceMethodType),
+                                             Objects.requireNonNull(implementation),
+                                             Objects.requireNonNull(dynamicMethodType),
+                                             false,
+                                             EMPTY_CLASS_ARRAY,
+                                             EMPTY_MT_ARRAY);
         mf.validateMetafactoryArgs();
         return mf.buildCallSite();
     }
@@ -350,8 +363,8 @@ public final class LambdaMetafactory {
      *
      * <pre>{@code
      *  CallSite altMetafactory(MethodHandles.Lookup caller,
-     *                          String invokedName,
-     *                          MethodType invokedType,
+     *                          String interfaceMethodName,
+     *                          MethodType factoryType,
      *                          Object... args)
      * }</pre>
      *
@@ -359,16 +372,16 @@ public final class LambdaMetafactory {
      *
      * <pre>{@code
      *  CallSite altMetafactory(MethodHandles.Lookup caller,
-     *                          String invokedName,
-     *                          MethodType invokedType,
-     *                          MethodType samMethodType,
-     *                          MethodHandle implMethod,
-     *                          MethodType instantiatedMethodType,
+     *                          String interfaceMethodName,
+     *                          MethodType factoryType,
+     *                          MethodType interfaceMethodType,
+     *                          MethodHandle implementation,
+     *                          MethodType dynamicMethodType,
      *                          int flags,
-     *                          int markerInterfaceCount,  // IF flags has MARKERS set
-     *                          Class... markerInterfaces, // IF flags has MARKERS set
-     *                          int bridgeCount,           // IF flags has BRIDGES set
-     *                          MethodType... bridges      // IF flags has BRIDGES set
+     *                          int altInterfaceCount,        // IF flags has MARKERS set
+     *                          Class... altInterfaces,       // IF flags has MARKERS set
+     *                          int altMethodCount,           // IF flags has BRIDGES set
+     *                          MethodType... altMethods      // IF flags has BRIDGES set
      *                          )
      * }</pre>
      *
@@ -380,25 +393,25 @@ public final class LambdaMetafactory {
      *     <li>{@code flags} indicates additional options; this is a bitwise
      *     OR of desired flags.  Defined flags are {@link #FLAG_BRIDGES},
      *     {@link #FLAG_MARKERS}, and {@link #FLAG_SERIALIZABLE}.</li>
-     *     <li>{@code markerInterfaceCount} is the number of additional interfaces
+     *     <li>{@code altInterfaceCount} is the number of additional interfaces
      *     the function object should implement, and is present if and only if the
      *     {@code FLAG_MARKERS} flag is set.</li>
-     *     <li>{@code markerInterfaces} is a variable-length list of additional
-     *     interfaces to implement, whose length equals {@code markerInterfaceCount},
+     *     <li>{@code altInterfaces} is a variable-length list of additional
+     *     interfaces to implement, whose length equals {@code altInterfaceCount},
      *     and is present if and only if the {@code FLAG_MARKERS} flag is set.</li>
-     *     <li>{@code bridgeCount} is the number of additional method signatures
+     *     <li>{@code altMethodCount} is the number of additional method signatures
      *     the function object should implement, and is present if and only if
      *     the {@code FLAG_BRIDGES} flag is set.</li>
-     *     <li>{@code bridges} is a variable-length list of additional
-     *     methods signatures to implement, whose length equals {@code bridgeCount},
+     *     <li>{@code altMethods} is a variable-length list of additional
+     *     methods signatures to implement, whose length equals {@code altMethodCount},
      *     and is present if and only if the {@code FLAG_BRIDGES} flag is set.</li>
      * </ul>
      *
-     * <p>Each class named by {@code markerInterfaces} is subject to the same
-     * restrictions as {@code Rd}, the return type of {@code invokedType},
+     * <p>Each class named by {@code altInterfaces} is subject to the same
+     * restrictions as {@code Rd}, the return type of {@code factoryType},
      * as described {@link LambdaMetafactory above}.  Each {@code MethodType}
-     * named by {@code bridges} is subject to the same restrictions as
-     * {@code samMethodType}, as described {@link LambdaMetafactory above}.
+     * named by {@code altMethods} is subject to the same restrictions as
+     * {@code interfaceMethodType}, as described {@link LambdaMetafactory above}.
      *
      * <p>When FLAG_SERIALIZABLE is set in {@code flags}, the function objects
      * will implement {@code Serializable}, and will have a {@code writeReplace}
@@ -411,10 +424,10 @@ public final class LambdaMetafactory {
      * the following properties:
      * <ul>
      *     <li>The class implements the interface named by the return type
-     *     of {@code invokedType} and any interfaces named by {@code markerInterfaces}</li>
-     *     <li>The class declares methods with the name given by {@code invokedName},
-     *     and the signature given by {@code samMethodType} and additional signatures
-     *     given by {@code bridges}</li>
+     *     of {@code factoryType} and any interfaces named by {@code altInterfaces}</li>
+     *     <li>The class declares methods with the name given by {@code interfaceMethodName},
+     *     and the signature given by {@code interfaceMethodType} and additional signatures
+     *     given by {@code altMethods}</li>
      *     <li>The class may override methods from {@code Object}, and may
      *     implement methods related to serialization.</li>
      * </ul>
@@ -425,80 +438,122 @@ public final class LambdaMetafactory {
      *               full privilege access}.
      *               When used with {@code invokedynamic}, this is stacked
      *               automatically by the VM.
-     * @param invokedName The name of the method to implement.  When used with
-     *                    {@code invokedynamic}, this is provided by the
-     *                    {@code NameAndType} of the {@code InvokeDynamic}
-     *                    structure and is stacked automatically by the VM.
-     * @param invokedType The expected signature of the {@code CallSite}.  The
+     * @param interfaceMethodName The name of the method to implement.  When used with
+     *                            {@code invokedynamic}, this is provided by the
+     *                            {@code NameAndType} of the {@code InvokeDynamic}
+     *                            structure and is stacked automatically by the VM.
+     * @param factoryType The expected signature of the {@code CallSite}.  The
      *                    parameter types represent the types of capture variables;
      *                    the return type is the interface to implement.   When
      *                    used with {@code invokedynamic}, this is provided by
      *                    the {@code NameAndType} of the {@code InvokeDynamic}
      *                    structure and is stacked automatically by the VM.
-     *                    In the event that the implementation method is an
-     *                    instance method and this signature has any parameters,
-     *                    the first parameter in the invocation signature must
-     *                    correspond to the receiver.
-     * @param  args       An {@code Object[]} array containing the required
-     *                    arguments {@code samMethodType}, {@code implMethod},
-     *                    {@code instantiatedMethodType}, {@code flags}, and any
-     *                    optional arguments, as described
-     *                    {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)} above}
+     * @param  args An array of {@code Object} containing the required
+     *              arguments {@code interfaceMethodType}, {@code implementation},
+     *              {@code dynamicMethodType}, {@code flags}, and any
+     *              optional arguments, as described above
      * @return a CallSite whose target can be used to perform capture, generating
-     *         instances of the interface named by {@code invokedType}
-     * @throws LambdaConversionException If any of the linkage invariants
-     *                                   described {@link LambdaMetafactory above}
-     *                                   are violated, or the lookup context
-     *                                   does not have private access privileges.
+     *         instances of the interface named by {@code factoryType}
+     * @throws LambdaConversionException If {@code caller} does not have full privilege
+     *         access, or if {@code interfaceMethodName} is not a valid JVM
+     *         method name, or if the return type of {@code factoryType} is not
+     *         an interface, or if any of {@code altInterfaces} is not an
+     *         interface, or if {@code implementation} is not a direct method
+     *         handle referencing a method or constructor, or if the linkage
+     *         invariants are violated, as defined {@link LambdaMetafactory above}.
+     * @throws NullPointerException If any argument, or any component of {@code args},
+     *         is {@code null}.
+     * @throws IllegalArgumentException If the number or types of the components
+     *         of {@code args} do not follow the above rules, or if
+     *         {@code altInterfaceCount} or {@code altMethodCount} are negative
+     *         integers.
+     * @throws SecurityException If a security manager is present, and it
+     *         <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+     *         from {@code caller} to the package of {@code implementation}.
      */
     public static CallSite altMetafactory(MethodHandles.Lookup caller,
-                                          String invokedName,
-                                          MethodType invokedType,
+                                          String interfaceMethodName,
+                                          MethodType factoryType,
                                           Object... args)
             throws LambdaConversionException {
-        MethodType samMethodType = (MethodType)args[0];
-        MethodHandle implMethod = (MethodHandle)args[1];
-        MethodType instantiatedMethodType = (MethodType)args[2];
-        int flags = (Integer) args[3];
-        Class<?>[] markerInterfaces;
-        MethodType[] bridges;
-        int argIndex = 4;
+        Objects.requireNonNull(caller);
+        Objects.requireNonNull(interfaceMethodName);
+        Objects.requireNonNull(factoryType);
+        Objects.requireNonNull(args);
+        int argIndex = 0;
+        MethodType interfaceMethodType = extractArg(args, argIndex++, MethodType.class);
+        MethodHandle implementation = extractArg(args, argIndex++, MethodHandle.class);
+        MethodType dynamicMethodType = extractArg(args, argIndex++, MethodType.class);
+        int flags = extractArg(args, argIndex++, Integer.class);
+        Class<?>[] altInterfaces = EMPTY_CLASS_ARRAY;
+        MethodType[] altMethods = EMPTY_MT_ARRAY;
         if ((flags & FLAG_MARKERS) != 0) {
-            int markerCount = (Integer) args[argIndex++];
-            markerInterfaces = new Class<?>[markerCount];
-            System.arraycopy(args, argIndex, markerInterfaces, 0, markerCount);
-            argIndex += markerCount;
+            int altInterfaceCount = extractArg(args, argIndex++, Integer.class);
+            if (altInterfaceCount < 0) {
+                throw new IllegalArgumentException("negative argument count");
+            }
+            if (altInterfaceCount > 0) {
+                altInterfaces = extractArgs(args, argIndex, Class.class, altInterfaceCount);
+                argIndex += altInterfaceCount;
+            }
         }
-        else
-            markerInterfaces = EMPTY_CLASS_ARRAY;
         if ((flags & FLAG_BRIDGES) != 0) {
-            int bridgeCount = (Integer) args[argIndex++];
-            bridges = new MethodType[bridgeCount];
-            System.arraycopy(args, argIndex, bridges, 0, bridgeCount);
-            argIndex += bridgeCount;
+            int altMethodCount = extractArg(args, argIndex++, Integer.class);
+            if (altMethodCount < 0) {
+                throw new IllegalArgumentException("negative argument count");
+            }
+            if (altMethodCount > 0) {
+                altMethods = extractArgs(args, argIndex, MethodType.class, altMethodCount);
+                argIndex += altMethodCount;
+            }
+        }
+        if (argIndex < args.length) {
+            throw new IllegalArgumentException("too many arguments");
         }
-        else
-            bridges = EMPTY_MT_ARRAY;
 
         boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0);
         if (isSerializable) {
-            boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType());
-            for (Class<?> c : markerInterfaces)
+            boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(factoryType.returnType());
+            for (Class<?> c : altInterfaces)
                 foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
             if (!foundSerializableSupertype) {
-                markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1);
-                markerInterfaces[markerInterfaces.length-1] = Serializable.class;
+                altInterfaces = Arrays.copyOf(altInterfaces, altInterfaces.length + 1);
+                altInterfaces[altInterfaces.length-1] = Serializable.class;
             }
         }
 
         AbstractValidatingLambdaMetafactory mf
-                = new InnerClassLambdaMetafactory(caller, invokedType,
-                                                  invokedName, samMethodType,
-                                                  implMethod,
-                                                  instantiatedMethodType,
+                = new InnerClassLambdaMetafactory(caller,
+                                                  factoryType,
+                                                  interfaceMethodName,
+                                                  interfaceMethodType,
+                                                  implementation,
+                                                  dynamicMethodType,
                                                   isSerializable,
-                                                  markerInterfaces, bridges);
+                                                  altInterfaces,
+                                                  altMethods);
         mf.validateMetafactoryArgs();
         return mf.buildCallSite();
     }
+
+    private static <T> T extractArg(Object[] args, int index, Class<T> type) {
+        if (index >= args.length) {
+            throw new IllegalArgumentException("missing argument");
+        }
+        Object result = Objects.requireNonNull(args[index]);
+        if (!type.isInstance(result)) {
+            throw new IllegalArgumentException("argument has wrong type");
+        }
+        return type.cast(result);
+    }
+
+    private static <T> T[] extractArgs(Object[] args, int index, Class<T> type, int count) {
+        @SuppressWarnings("unchecked")
+        T[] result = (T[]) Array.newInstance(type, count);
+        for (int i = 0; i < count; i++) {
+            result[i] = extractArg(args, index + i, type);
+        }
+        return result;
+    }
+
 }
