/*
 * Copyright (c) 2008, 2011, 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
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.invoke.util;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;

public class ValueConversions {
    private static final Class<?> THIS_CLASS = ValueConversions.class;
    // Do not adjust this except for special platforms:
    private static final int MAX_ARITY;
    static {
        final Object[] values = { 255 };
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    values[0] = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
                    return null;
                }
            });
        MAX_ARITY = (Integer) values[0];
    }

    private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();

    private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
        @SuppressWarnings("unchecked")  // generic array creation
        EnumMap<Wrapper, MethodHandle>[] caches
                = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap<?,?>[n];
        for (int i = 0; i < n; i++)
            caches[i] = new EnumMap<>(Wrapper.class);
        return caches;
    }

    /// Converting references to values.

    // There are several levels of this unboxing conversions:
    //   no conversions:  exactly Integer.valueOf, etc.
    //   implicit conversions sanctioned by JLS 5.1.2, etc.
    //   explicit conversions as allowed by explicitCastArguments

    static int unboxInteger(Object x, boolean cast) {
        if (x instanceof Integer)
            return ((Integer) x).intValue();
        return primitiveConversion(Wrapper.INT, x, cast).intValue();
    }

    static byte unboxByte(Object x, boolean cast) {
        if (x instanceof Byte)
            return ((Byte) x).byteValue();
        return primitiveConversion(Wrapper.BYTE, x, cast).byteValue();
    }

    static short unboxShort(Object x, boolean cast) {
        if (x instanceof Short)
            return ((Short) x).shortValue();
        return primitiveConversion(Wrapper.SHORT, x, cast).shortValue();
    }

    static boolean unboxBoolean(Object x, boolean cast) {
        if (x instanceof Boolean)
            return ((Boolean) x).booleanValue();
        return (primitiveConversion(Wrapper.BOOLEAN, x, cast).intValue() & 1) != 0;
    }

    static char unboxCharacter(Object x, boolean cast) {
        if (x instanceof Character)
            return ((Character) x).charValue();
        return (char) primitiveConversion(Wrapper.CHAR, x, cast).intValue();
    }

    static long unboxLong(Object x, boolean cast) {
        if (x instanceof Long)
            return ((Long) x).longValue();
        return primitiveConversion(Wrapper.LONG, x, cast).longValue();
    }

    static float unboxFloat(Object x, boolean cast) {
        if (x instanceof Float)
            return ((Float) x).floatValue();
        return primitiveConversion(Wrapper.FLOAT, x, cast).floatValue();
    }

    static double unboxDouble(Object x, boolean cast) {
        if (x instanceof Double)
            return ((Double) x).doubleValue();
        return primitiveConversion(Wrapper.DOUBLE, x, cast).doubleValue();
    }

    /// Converting references to "raw" values.
    /// A raw primitive value is always an int or long.

    static int unboxByteRaw(Object x, boolean cast) {
        return unboxByte(x, cast);
    }

    static int unboxShortRaw(Object x, boolean cast) {
        return unboxShort(x, cast);
    }

    static int unboxBooleanRaw(Object x, boolean cast) {
        return unboxBoolean(x, cast) ? 1 : 0;
    }

    static int unboxCharacterRaw(Object x, boolean cast) {
        return unboxCharacter(x, cast);
    }

    static int unboxFloatRaw(Object x, boolean cast) {
        return Float.floatToIntBits(unboxFloat(x, cast));
    }

    static long unboxDoubleRaw(Object x, boolean cast) {
        return Double.doubleToRawLongBits(unboxDouble(x, cast));
    }

    private static MethodType unboxType(Wrapper wrap, boolean raw) {
        return MethodType.methodType(rawWrapper(wrap, raw).primitiveType(), Object.class, boolean.class);
    }

    private static final EnumMap<Wrapper, MethodHandle>[]
            UNBOX_CONVERSIONS = newWrapperCaches(4);

    private static MethodHandle unbox(Wrapper wrap, boolean raw, boolean cast) {
        EnumMap<Wrapper, MethodHandle> cache = UNBOX_CONVERSIONS[(cast?1:0)+(raw?2:0)];
        MethodHandle mh = cache.get(wrap);
        if (mh != null) {
            return mh;
        }
        // slow path
        switch (wrap) {
            case OBJECT:
                mh = IDENTITY; break;
            case VOID:
                mh = raw ? ALWAYS_ZERO : IGNORE; break;
            case INT: case LONG:
                // these guys don't need separate raw channels
                if (raw)  mh = unbox(wrap, false, cast);
                break;
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }
        // look up the method
        String name = "unbox" + wrap.simpleName() + (raw ? "Raw" : "");
        MethodType type = unboxType(wrap, raw);
        try {
            mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
        } catch (ReflectiveOperationException ex) {
            mh = null;
        }
        if (mh != null) {
            mh = MethodHandles.insertArguments(mh, 1, cast);
            cache.put(wrap, mh);
            return mh;
        }
        throw new IllegalArgumentException("cannot find unbox adapter for " + wrap
                + (cast ? " (cast)" : "") + (raw ? " (raw)" : ""));
    }

    public static MethodHandle unboxCast(Wrapper type) {
        return unbox(type, false, true);
    }

    public static MethodHandle unboxRaw(Wrapper type) {
        return unbox(type, true, false);
    }

    public static MethodHandle unbox(Class<?> type) {
        return unbox(Wrapper.forPrimitiveType(type), false, false);
    }

    public static MethodHandle unboxCast(Class<?> type) {
        return unbox(Wrapper.forPrimitiveType(type), false, true);
    }

    public static MethodHandle unboxRaw(Class<?> type) {
        return unbox(Wrapper.forPrimitiveType(type), true, false);
    }

    static private final Integer ZERO_INT = 0, ONE_INT = 1;

    /// Primitive conversions
    public static Number primitiveConversion(Wrapper wrap, Object x, boolean cast) {
        // Maybe merge this code with Wrapper.convert/cast.
        Number res = null;
        if (x == null) {
            if (!cast)  return null;
            return ZERO_INT;
        }
        if (x instanceof Number) {
            res = (Number) x;
        } else if (x instanceof Boolean) {
            res = ((boolean)x ? ONE_INT : ZERO_INT);
        } else if (x instanceof Character) {
            res = (int)(char)x;
        } else {
            // this will fail with the required ClassCastException:
            res = (Number) x;
        }
        Wrapper xwrap = Wrapper.findWrapperType(x.getClass());
        if (xwrap == null || !cast && !wrap.isConvertibleFrom(xwrap))
            // this will fail with the required ClassCastException:
            return (Number) wrap.wrapperType().cast(x);
        return res;
    }

    /// Converting primitives to references

    static Integer boxInteger(int x) {
        return x;
    }

    static Byte boxByte(byte x) {
        return x;
    }

    static Short boxShort(short x) {
        return x;
    }

    static Boolean boxBoolean(boolean x) {
        return x;
    }

    static Character boxCharacter(char x) {
        return x;
    }

    static Long boxLong(long x) {
        return x;
    }

    static Float boxFloat(float x) {
        return x;
    }

    static Double boxDouble(double x) {
        return x;
    }

    /// Converting raw primitives to references

    static Byte boxByteRaw(int x) {
        return boxByte((byte)x);
    }

    static Short boxShortRaw(int x) {
        return boxShort((short)x);
    }

    static Boolean boxBooleanRaw(int x) {
        return boxBoolean(x != 0);
    }

    static Character boxCharacterRaw(int x) {
        return boxCharacter((char)x);
    }

    static Float boxFloatRaw(int x) {
        return boxFloat(Float.intBitsToFloat(x));
    }

    static Double boxDoubleRaw(long x) {
        return boxDouble(Double.longBitsToDouble(x));
    }

    // a raw void value is (arbitrarily) a garbage int
    static Void boxVoidRaw(int x) {
        return null;
    }

    private static MethodType boxType(Wrapper wrap, boolean raw) {
        // be exact, since return casts are hard to compose
        Class<?> boxType = wrap.wrapperType();
        return MethodType.methodType(boxType, rawWrapper(wrap, raw).primitiveType());
    }

    private static Wrapper rawWrapper(Wrapper wrap, boolean raw) {
        if (raw)  return wrap.isDoubleWord() ? Wrapper.LONG : Wrapper.INT;
        return wrap;
    }

    private static final EnumMap<Wrapper, MethodHandle>[]
            BOX_CONVERSIONS = newWrapperCaches(4);

    private static MethodHandle box(Wrapper wrap, boolean exact, boolean raw) {
        EnumMap<Wrapper, MethodHandle> cache = BOX_CONVERSIONS[(exact?1:0)+(raw?2:0)];
        MethodHandle mh = cache.get(wrap);
        if (mh != null) {
            return mh;
        }
        // slow path
        switch (wrap) {
            case OBJECT:
                mh = IDENTITY; break;
            case VOID:
                if (!raw)  mh = ZERO_OBJECT;
                break;
            case INT: case LONG:
                // these guys don't need separate raw channels
                if (raw)  mh = box(wrap, exact, false);
                break;
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }
        // look up the method
        String name = "box" + wrap.simpleName() + (raw ? "Raw" : "");
        MethodType type = boxType(wrap, raw);
        if (exact) {
            try {
                mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
            } catch (ReflectiveOperationException ex) {
                mh = null;
            }
        } else {
            mh = box(wrap, !exact, raw).asType(type.erase());
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }
        throw new IllegalArgumentException("cannot find box adapter for "
                + wrap + (exact ? " (exact)" : "") + (raw ? " (raw)" : ""));
    }

    public static MethodHandle box(Class<?> type) {
        boolean exact = false;
        // e.g., boxShort(short)Short if exact,
        // e.g., boxShort(short)Object if !exact
        return box(Wrapper.forPrimitiveType(type), exact, false);
    }

    public static MethodHandle boxRaw(Class<?> type) {
        boolean exact = false;
        // e.g., boxShortRaw(int)Short if exact
        // e.g., boxShortRaw(int)Object if !exact
        return box(Wrapper.forPrimitiveType(type), exact, true);
    }

    public static MethodHandle box(Wrapper type) {
        boolean exact = false;
        return box(type, exact, false);
    }

    public static MethodHandle boxRaw(Wrapper type) {
        boolean exact = false;
        return box(type, exact, true);
    }

    /// Kludges for when raw values get accidentally boxed.

    static int unboxRawInteger(Object x) {
        if (x instanceof Integer)
            return (int) x;
        else
            return (int) unboxLong(x, false);
    }

    static Integer reboxRawInteger(Object x) {
        if (x instanceof Integer)
            return (Integer) x;
        else
            return (int) unboxLong(x, false);
    }

    static Byte reboxRawByte(Object x) {
        if (x instanceof Byte)  return (Byte) x;
        return boxByteRaw(unboxRawInteger(x));
    }

    static Short reboxRawShort(Object x) {
        if (x instanceof Short)  return (Short) x;
        return boxShortRaw(unboxRawInteger(x));
    }

    static Boolean reboxRawBoolean(Object x) {
        if (x instanceof Boolean)  return (Boolean) x;
        return boxBooleanRaw(unboxRawInteger(x));
    }

    static Character reboxRawCharacter(Object x) {
        if (x instanceof Character)  return (Character) x;
        return boxCharacterRaw(unboxRawInteger(x));
    }

    static Float reboxRawFloat(Object x) {
        if (x instanceof Float)  return (Float) x;
        return boxFloatRaw(unboxRawInteger(x));
    }

    static Long reboxRawLong(Object x) {
        return (Long) x;  //never a rebox
    }

    static Double reboxRawDouble(Object x) {
        if (x instanceof Double)  return (Double) x;
        return boxDoubleRaw(unboxLong(x, true));
    }

    private static MethodType reboxType(Wrapper wrap) {
        Class<?> boxType = wrap.wrapperType();
        return MethodType.methodType(boxType, Object.class);
    }

    private static final EnumMap<Wrapper, MethodHandle>[]
            REBOX_CONVERSIONS = newWrapperCaches(1);

    /**
     * Because we normalize primitive types to reduce the number of signatures,
     * primitives are sometimes manipulated under an "erased" type,
     * either int (for types other than long/double) or long (for all types).
     * When the erased primitive value is then boxed into an Integer or Long,
     * the final boxed primitive is sometimes required.  This transformation
     * is called a "rebox".  It takes an Integer or Long and produces some
     * other boxed value, typed (inexactly) as an Object
     */
    public static MethodHandle rebox(Wrapper wrap) {
        EnumMap<Wrapper, MethodHandle> cache = REBOX_CONVERSIONS[0];
        MethodHandle mh = cache.get(wrap);
        if (mh != null) {
            return mh;
        }
        // slow path
        switch (wrap) {
            case OBJECT:
                mh = IDENTITY; break;
            case VOID:
                throw new IllegalArgumentException("cannot rebox a void");
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }
        // look up the method
        String name = "reboxRaw" + wrap.simpleName();
        MethodType type = reboxType(wrap);
        try {
            mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
            mh = mh.asType(IDENTITY.type());
        } catch (ReflectiveOperationException ex) {
            mh = null;
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }
        throw new IllegalArgumentException("cannot find rebox adapter for " + wrap);
    }

    public static MethodHandle rebox(Class<?> type) {
        return rebox(Wrapper.forPrimitiveType(type));
    }

    /// Width-changing conversions between int and long.

    static long widenInt(int x) {
        return (long) x;
    }

    static Long widenBoxedInt(Integer x) {
        return (long)(int)x;
    }

    static int narrowLong(long x) {
        return (int) x;
    }

    static Integer narrowBoxedLong(Long x) {
        return (int)(long) x;
    }

    /// Constant functions

    static void ignore(Object x) {
        // no value to return; this is an unbox of null
        return;
    }

    static void empty() {
        return;
    }

    static Object zeroObject() {
        return null;
    }

    static int zeroInteger() {
        return 0;
    }

    static long zeroLong() {
        return 0;
    }

    static float zeroFloat() {
        return 0;
    }

    static double zeroDouble() {
        return 0;
    }

    private static final EnumMap<Wrapper, MethodHandle>[]
            CONSTANT_FUNCTIONS = newWrapperCaches(2);

    public static MethodHandle zeroConstantFunction(Wrapper wrap) {
        EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[0];
        MethodHandle mh = cache.get(wrap);
        if (mh != null) {
            return mh;
        }
        // slow path
        MethodType type = MethodType.methodType(wrap.primitiveType());
        switch (wrap) {
            case VOID:
                mh = EMPTY;
                break;
            case OBJECT:
            case INT: case LONG: case FLOAT: case DOUBLE:
                try {
                    mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.simpleName(), type);
                } catch (ReflectiveOperationException ex) {
                    mh = null;
                }
                break;
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }

        // use the raw method
        Wrapper rawWrap = wrap.rawPrimitive();
        if (mh == null && rawWrap != wrap) {
            mh = MethodHandles.explicitCastArguments(zeroConstantFunction(rawWrap), type);
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }
        throw new IllegalArgumentException("cannot find zero constant for " + wrap);
    }

    /// Converting references to references.

    /**
     * Value-killing function.
     * @param x an arbitrary reference value
     * @return a null
     */
    static Object alwaysNull(Object x) {
        return null;
    }

    /**
     * Value-killing function.
     * @param x an arbitrary reference value
     * @return a zero
     */
    static int alwaysZero(Object x) {
        return 0;
    }

    /**
     * Identity function.
     * @param x an arbitrary reference value
     * @return the same value x
     */
    static <T> T identity(T x) {
        return x;
    }

    /**
     * Identity function on ints.
     * @param x an arbitrary int value
     * @return the same value x
     */
    static int identity(int x) {
        return x;
    }

    static byte identity(byte x) {
        return x;
    }

    static short identity(short x) {
        return x;
    }

    static boolean identity(boolean x) {
        return x;
    }

    static char identity(char x) {
        return x;
    }

    /**
     * Identity function on longs.
     * @param x an arbitrary long value
     * @return the same value x
     */
    static long identity(long x) {
        return x;
    }

    static float identity(float x) {
        return x;
    }

    static double identity(double x) {
        return x;
    }

    /**
     * Identity function, with reference cast.
     * @param t an arbitrary reference type
     * @param x an arbitrary reference value
     * @return the same value x
     */
    static <T,U> T castReference(Class<? extends T> t, U x) {
        return t.cast(x);
    }

    private static final MethodHandle IDENTITY, IDENTITY_I, IDENTITY_J, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY, NEW_ARRAY;
    static {
        try {
            MethodType idType = MethodType.genericMethodType(1);
            MethodType castType = idType.insertParameterTypes(0, Class.class);
            MethodType alwaysZeroType = idType.changeReturnType(int.class);
            MethodType ignoreType = idType.changeReturnType(void.class);
            MethodType zeroObjectType = MethodType.genericMethodType(0);
            IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
            IDENTITY_I = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(int.class, int.class));
            IDENTITY_J = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(long.class, long.class));
            //CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
            CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType);
            ALWAYS_NULL = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysNull", idType);
            ALWAYS_ZERO = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysZero", alwaysZeroType);
            ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
            IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
            EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
            NEW_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "newArray", MethodType.methodType(Object[].class, int.class));
        } catch (NoSuchMethodException | IllegalAccessException ex) {
            throw new InternalError("uncaught exception", ex);
        }
    }

    // Varargs methods need to be in a separately initialized class, to bootstrapping problems.
    static class LazyStatics {
        private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
        static {
            try {
                //MAKE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeArray", MethodType.methodType(Object[].class, Object[].class));
                COPY_AS_REFERENCE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsReferenceArray", MethodType.methodType(Object[].class, Class.class, Object[].class));
                COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class));
                MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class));
            } catch (ReflectiveOperationException ex) {
                throw new InternalError("uncaught exception", ex);
            }
        }
    }

    private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
            = newWrapperCaches(2);

    /** Return a method that casts its sole argument (an Object) to the given type
     *  and returns it as the given type (if exact is true), or as plain Object (if erase is true).
     */
    public static MethodHandle cast(Class<?> type) {
        boolean exact = false;
        if (type.isPrimitive())  throw new IllegalArgumentException("cannot cast primitive type "+type);
        MethodHandle mh = null;
        Wrapper wrap = null;
        EnumMap<Wrapper, MethodHandle> cache = null;
        if (Wrapper.isWrapperType(type)) {
            wrap = Wrapper.forWrapperType(type);
            cache = WRAPPER_CASTS[exact?1:0];
            mh = cache.get(wrap);
            if (mh != null)  return mh;
        }
        if (VerifyType.isNullReferenceConversion(Object.class, type))
            mh = IDENTITY;
        else if (VerifyType.isNullType(type))
            mh = ALWAYS_NULL;
        else
            mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
        if (exact) {
            MethodType xmt = MethodType.methodType(type, Object.class);
            mh = MethodHandles.explicitCastArguments(mh, xmt);
            //mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh);
        }
        if (cache != null)
            cache.put(wrap, mh);
        return mh;
    }

    public static MethodHandle identity() {
        return IDENTITY;
    }

    public static MethodHandle identity(Class<?> type) {
        // This stuff has been moved into MethodHandles:
        return MethodHandles.identity(type);
    }

    public static MethodHandle identity(Wrapper wrap) {
        EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[1];
        MethodHandle mh = cache.get(wrap);
        if (mh != null) {
            return mh;
        }
        // slow path
        MethodType type = MethodType.methodType(wrap.primitiveType());
        if (wrap != Wrapper.VOID)
            type = type.appendParameterTypes(wrap.primitiveType());
        try {
            mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", type);
        } catch (ReflectiveOperationException ex) {
            mh = null;
        }
        if (mh == null && wrap == Wrapper.VOID) {
            mh = EMPTY;  // #(){} : #()void
        }
        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }

        if (mh != null) {
            cache.put(wrap, mh);
            return mh;
        }
        throw new IllegalArgumentException("cannot find identity for " + wrap);
    }

    /// Float/non-float conversions.

    static float doubleToFloat(double x) {
        return (float) x;
    }
    static double floatToDouble(float x) {
        return x;
    }

    // narrow double to integral type
    static long doubleToLong(double x) {
        return (long) x;
    }
    static int doubleToInt(double x) {
        return (int) x;
    }
    static short doubleToShort(double x) {
        return (short) x;
    }
    static char doubleToChar(double x) {
        return (char) x;
    }
    static byte doubleToByte(double x) {
        return (byte) x;
    }
    static boolean doubleToBoolean(double x) {
        return toBoolean((byte) x);
    }

    // narrow float to integral type
    static long floatToLong(float x) {
        return (long) x;
    }
    static int floatToInt(float x) {
        return (int) x;
    }
    static short floatToShort(float x) {
        return (short) x;
    }
    static char floatToChar(float x) {
        return (char) x;
    }
    static byte floatToByte(float x) {
        return (byte) x;
    }
    static boolean floatToBoolean(float x) {
        return toBoolean((byte) x);
    }

    // widen integral type to double
    static double longToDouble(long x) {
        return x;
    }
    static double intToDouble(int x) {
        return x;
    }
    static double shortToDouble(short x) {
        return x;
    }
    static double charToDouble(char x) {
        return x;
    }
    static double byteToDouble(byte x) {
        return x;
    }
    static double booleanToDouble(boolean x) {
        return fromBoolean(x);
    }

    // widen integral type to float
    static float longToFloat(long x) {
        return x;
    }
    static float intToFloat(int x) {
        return x;
    }
    static float shortToFloat(short x) {
        return x;
    }
    static float charToFloat(char x) {
        return x;
    }
    static float byteToFloat(byte x) {
        return x;
    }
    static float booleanToFloat(boolean x) {
        return fromBoolean(x);
    }

    static boolean toBoolean(byte x) {
        // see javadoc for MethodHandles.explicitCastArguments
        return ((x & 1) != 0);
    }
    static byte fromBoolean(boolean x) {
        // see javadoc for MethodHandles.explicitCastArguments
        return (x ? (byte)1 : (byte)0);
    }

    private static final EnumMap<Wrapper, MethodHandle>[]
            CONVERT_FLOAT_FUNCTIONS = newWrapperCaches(4);

    static MethodHandle convertFloatFunction(Wrapper wrap, boolean toFloat, boolean doubleSize) {
        EnumMap<Wrapper, MethodHandle> cache = CONVERT_FLOAT_FUNCTIONS[(toFloat?1:0)+(doubleSize?2:0)];
        MethodHandle mh = cache.get(wrap);
        if (mh != null) {
            return mh;
        }
        // slow path
        Wrapper fwrap = (doubleSize ? Wrapper.DOUBLE : Wrapper.FLOAT);
        Class<?> fix = wrap.primitiveType();
        Class<?> flt = (doubleSize ? double.class : float.class);
        Class<?> src = toFloat ? fix : flt;
        Class<?> dst = toFloat ? flt : fix;
        if (src == dst)  return identity(wrap);
        MethodType type = MethodType.methodType(dst, src);
        switch (wrap) {
            case VOID:
                mh = toFloat ? zeroConstantFunction(fwrap) : MethodHandles.dropArguments(EMPTY, 0, flt);
                break;
            case OBJECT:
                mh = toFloat ? unbox(flt) : box(flt);
                break;
            default:
                try {
                    mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type);
                } catch (ReflectiveOperationException ex) {
                    mh = null;
                }
                break;
        }
        if (mh != null) {
            assert(mh.type() == type) : mh;
            cache.put(wrap, mh);
            return mh;
        }

        throw new IllegalArgumentException("cannot find float conversion constant for " +
                                           src.getSimpleName()+" -> "+dst.getSimpleName());
    }

    public static MethodHandle convertFromFloat(Class<?> fixType) {
        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
        return convertFloatFunction(wrap, false, false);
    }
    public static MethodHandle convertFromDouble(Class<?> fixType) {
        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
        return convertFloatFunction(wrap, false, true);
    }
    public static MethodHandle convertToFloat(Class<?> fixType) {
        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
        return convertFloatFunction(wrap, true, false);
    }
    public static MethodHandle convertToDouble(Class<?> fixType) {
        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
        return convertFloatFunction(wrap, true, true);
    }

    private static String capitalize(String x) {
        return Character.toUpperCase(x.charAt(0))+x.substring(1);
    }

    /// Collection of multiple arguments.

    public static Object convertArrayElements(Class<?> arrayType, Object array) {
        Class<?> src = array.getClass().getComponentType();
        Class<?> dst = arrayType.getComponentType();
        if (src == null || dst == null)  throw new IllegalArgumentException("not array type");
        Wrapper sw = (src.isPrimitive() ? Wrapper.forPrimitiveType(src) : null);
        Wrapper dw = (dst.isPrimitive() ? Wrapper.forPrimitiveType(dst) : null);
        int length;
        if (sw == null) {
            Object[] a = (Object[]) array;
            length = a.length;
            if (dw == null)
                return Arrays.copyOf(a, length, arrayType.asSubclass(Object[].class));
            Object res = dw.makeArray(length);
            dw.copyArrayUnboxing(a, 0, res, 0, length);
            return res;
        }
        length = java.lang.reflect.Array.getLength(array);
        Object[] res;
        if (dw == null) {
            res = Arrays.copyOf(NO_ARGS_ARRAY, length, arrayType.asSubclass(Object[].class));
        } else {
            res = new Object[length];
        }
        sw.copyArrayBoxing(array, 0, res, 0, length);
        if (dw == null)  return res;
        Object a = dw.makeArray(length);
        dw.copyArrayUnboxing(res, 0, a, 0, length);
        return a;
    }

    private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
        MethodType type = MethodType.genericMethodType(nargs)
                .changeReturnType(rtype)
                .insertParameterTypes(0, ptypes);
        try {
            return IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
        } catch (ReflectiveOperationException ex) {
            return null;
        }
    }

    private static final Object[] NO_ARGS_ARRAY = {};
    private static Object[] makeArray(Object... args) { return args; }
    private static Object[] array() { return NO_ARGS_ARRAY; }
    private static Object[] array(Object a0)
                { return makeArray(a0); }
    private static Object[] array(Object a0, Object a1)
                { return makeArray(a0, a1); }
    private static Object[] array(Object a0, Object a1, Object a2)
                { return makeArray(a0, a1, a2); }
    private static Object[] array(Object a0, Object a1, Object a2, Object a3)
                { return makeArray(a0, a1, a2, a3); }
    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
                                  Object a4)
                { return makeArray(a0, a1, a2, a3, a4); }
    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5)
                { return makeArray(a0, a1, a2, a3, a4, a5); }
    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6)
                { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6, Object a7)
                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6, Object a7,
                                  Object a8)
                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6, Object a7,
                                  Object a8, Object a9)
                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
    private static MethodHandle[] makeArrays() {
        ArrayList<MethodHandle> mhs = new ArrayList<>();
        for (;;) {
            MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
            if (mh == null)  break;
            mhs.add(mh);
        }
        assert(mhs.size() == 11);  // current number of methods
        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
    }
    private static final MethodHandle[] ARRAYS = makeArrays();

    // mh-fill versions of the above:
    private static Object[] newArray(int len) { return new Object[len]; }
    private static void fillWithArguments(Object[] a, int pos, Object... args) {
        System.arraycopy(args, 0, a, pos, args.length);
    }
    // using Integer pos instead of int pos to avoid bootstrapping problems
    private static Object[] fillArray(Object[] a, Integer pos, Object a0)
                { fillWithArguments(a, pos, a0); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1)
                { fillWithArguments(a, pos, a0, a1); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2)
                { fillWithArguments(a, pos, a0, a1, a2); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3)
                { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
                                  Object a4)
                { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5)
                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6)
                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6, Object a7)
                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6, Object a7,
                                  Object a8)
                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
                                  Object a4, Object a5, Object a6, Object a7,
                                  Object a8, Object a9)
                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
    private static MethodHandle[] makeFillArrays() {
        ArrayList<MethodHandle> mhs = new ArrayList<>();
        mhs.add(null);  // there is no empty fill; at least a0 is required
        for (;;) {
            MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Object[].class, Integer.class);
            if (mh == null)  break;
            mhs.add(mh);
        }
        assert(mhs.size() == 11);  // current number of methods
        return mhs.toArray(new MethodHandle[0]);
    }
    private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();

    private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {
        return Arrays.copyOf(a, a.length, arrayType);
    }
    private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
        Object a = w.makeArray(boxes.length);
        w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
        return a;
    }

    /** Return a method handle that takes the indicated number of Object
     *  arguments and returns an Object array of them, as if for varargs.
     */
    public static MethodHandle varargsArray(int nargs) {
        MethodHandle mh = ARRAYS[nargs];
        if (mh != null)  return mh;
        mh = findCollector("array", nargs, Object[].class);
        if (mh != null)  return ARRAYS[nargs] = mh;
        MethodHandle producer = filler(0);  // identity function produces result
        return ARRAYS[nargs] = buildVarargsArray(producer, nargs);
    }

    private static MethodHandle buildVarargsArray(MethodHandle producer, int nargs) {
        // Build up the result mh as a sequence of fills like this:
        //   producer(fill(fill(fill(newArray(23),0,x1..x10),10,x11..x20),20,x21..x23))
        // The various fill(_,10*I,___*[J]) are reusable.
        MethodHandle filler = filler(nargs);
        MethodHandle mh = producer;
        mh = MethodHandles.dropArguments(mh, 1, filler.type().parameterList());
        mh = MethodHandles.foldArguments(mh, filler);
        mh = MethodHandles.foldArguments(mh, buildNewArray(nargs));
        return mh;
    }

    private static MethodHandle buildNewArray(int nargs) {
        return MethodHandles.insertArguments(NEW_ARRAY, 0, nargs);
    }

    private static final MethodHandle[] FILLERS = new MethodHandle[MAX_ARITY+1];
    // filler(N).invoke(a, arg0..arg[N-1]) fills a[0]..a[N-1]
    private static MethodHandle filler(int nargs) {
        MethodHandle filler = FILLERS[nargs];
        if (filler != null)  return filler;
        return FILLERS[nargs] = buildFiller(nargs);
    }
    private static MethodHandle buildFiller(int nargs) {
        if (nargs == 0)
            return MethodHandles.identity(Object[].class);
        final int CHUNK = (FILL_ARRAYS.length - 1);
        int rightLen = nargs % CHUNK;
        int leftLen = nargs - rightLen;
        if (rightLen == 0) {
            leftLen = nargs - (rightLen = CHUNK);
            if (FILLERS[leftLen] == null) {
                // build some precursors from left to right
                for (int j = 0; j < leftLen; j += CHUNK)  filler(j);
            }
        }
        MethodHandle leftFill = filler(leftLen);  // recursive fill
        MethodHandle rightFill = FILL_ARRAYS[rightLen];
        rightFill = MethodHandles.insertArguments(rightFill, 1, leftLen);  // [leftLen..nargs-1]

        // Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
        MethodHandle mh = filler(0);  // identity function produces result
        mh = MethodHandles.dropArguments(mh, 1, rightFill.type().parameterList());
        mh = MethodHandles.foldArguments(mh, rightFill);
        if (leftLen > 0) {
            mh = MethodHandles.dropArguments(mh, 1, leftFill.type().parameterList());
            mh = MethodHandles.foldArguments(mh, leftFill);
        }
        return mh;
    }

    // Type-polymorphic version of varargs maker.
    private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
        = new ClassValue<MethodHandle[]>() {
            protected MethodHandle[] computeValue(Class<?> type) {
                return new MethodHandle[256];
            }
    };

    /** Return a method handle that takes the indicated number of
     *  typed arguments and returns an array of them.
     *  The type argument is the array type.
     */
    public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
        Class<?> elemType = arrayType.getComponentType();
        if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
        // FIXME: Need more special casing and caching here.
        if (elemType == Object.class)
            return varargsArray(nargs);
        // other cases:  primitive arrays, subtypes of Object[]
        MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
        MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
        if (mh != null)  return mh;
        MethodHandle producer = buildArrayProducer(arrayType);
        mh = buildVarargsArray(producer, nargs);
        mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
        cache[nargs] = mh;
        return mh;
    }

    private static MethodHandle buildArrayProducer(Class<?> arrayType) {
        Class<?> elemType = arrayType.getComponentType();
        if (elemType.isPrimitive())
            return LazyStatics.COPY_AS_PRIMITIVE_ARRAY.bindTo(Wrapper.forPrimitiveType(elemType));
        else
            return LazyStatics.COPY_AS_REFERENCE_ARRAY.bindTo(arrayType);
    }

    // List version of varargs maker.

    private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
    private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
    private static List<Object> list() { return NO_ARGS_LIST; }
    private static List<Object> list(Object a0)
                { return makeList(a0); }
    private static List<Object> list(Object a0, Object a1)
                { return makeList(a0, a1); }
    private static List<Object> list(Object a0, Object a1, Object a2)
                { return makeList(a0, a1, a2); }
    private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
                { return makeList(a0, a1, a2, a3); }
    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
                                     Object a4)
                { return makeList(a0, a1, a2, a3, a4); }
    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
                                     Object a4, Object a5)
                { return makeList(a0, a1, a2, a3, a4, a5); }
    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
                                     Object a4, Object a5, Object a6)
                { return makeList(a0, a1, a2, a3, a4, a5, a6); }
    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
                                     Object a4, Object a5, Object a6, Object a7)
                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
                                     Object a4, Object a5, Object a6, Object a7,
                                     Object a8)
                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
                                     Object a4, Object a5, Object a6, Object a7,
                                     Object a8, Object a9)
                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
    private static MethodHandle[] makeLists() {
        ArrayList<MethodHandle> mhs = new ArrayList<>();
        for (;;) {
            MethodHandle mh = findCollector("list", mhs.size(), List.class);
            if (mh == null)  break;
            mhs.add(mh);
        }
        assert(mhs.size() == 11);  // current number of methods
        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
    }
    private static final MethodHandle[] LISTS = makeLists();

    /** Return a method handle that takes the indicated number of Object
     *  arguments and returns a List.
     */
    public static MethodHandle varargsList(int nargs) {
        MethodHandle mh = LISTS[nargs];
        if (mh != null)  return mh;
        mh = findCollector("list", nargs, List.class);
        if (mh != null)  return LISTS[nargs] = mh;
        return LISTS[nargs] = buildVarargsList(nargs);
    }
    private static MethodHandle buildVarargsList(int nargs) {
        return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST);
    }
}
