/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.invoke.WrongMethodTypeException;

public class Main {
  public static void main(String[] args) throws Throwable {
    testThrowException();
    testDropArguments();
    testCatchException();
    testGuardWithTest();
    testArrayElementGetter();
    testArrayElementSetter();
    testIdentity();
    testConstant();
    testBindTo();
    testFilterReturnValue();
    testPermuteArguments();
    testInvokers();
    testSpreaders_reference();
    testSpreaders_primitive();
  }

  public static void testThrowException() throws Throwable {
    MethodHandle handle = MethodHandles.throwException(String.class,
        IllegalArgumentException.class);

    if (handle.type().returnType() != String.class) {
      fail("Unexpected return type for handle: " + handle +
          " [ " + handle.type() + "]");
    }

    final IllegalArgumentException iae = new IllegalArgumentException("boo!");
    try {
      handle.invoke(iae);
      fail("Expected an exception of type: java.lang.IllegalArgumentException");
    } catch (IllegalArgumentException expected) {
      if (expected != iae) {
        fail("Wrong exception: expected " + iae + " but was " + expected);
      }
    }
  }

  public static void dropArguments_delegate(String message, long message2) {
    System.out.println("Message: " + message + ", Message2: " + message2);
  }

  public static void testDropArguments() throws Throwable {
    MethodHandle delegate = MethodHandles.lookup().findStatic(Main.class,
        "dropArguments_delegate",
        MethodType.methodType(void.class, new Class<?>[] { String.class, long.class }));

    MethodHandle transform = MethodHandles.dropArguments(delegate, 0, int.class, Object.class);

    // The transformer will accept two additional arguments at position zero.
    try {
      transform.invokeExact("foo", 42l);
      fail();
    } catch (WrongMethodTypeException expected) {
    }

    transform.invokeExact(45, new Object(), "foo", 42l);
    transform.invoke(45, new Object(), "foo", 42l);

    // Additional arguments at position 1.
    transform = MethodHandles.dropArguments(delegate, 1, int.class, Object.class);
    transform.invokeExact("foo", 45, new Object(), 42l);
    transform.invoke("foo", 45, new Object(), 42l);

    // Additional arguments at position 2.
    transform = MethodHandles.dropArguments(delegate, 2, int.class, Object.class);
    transform.invokeExact("foo", 42l, 45, new Object());
    transform.invoke("foo", 42l, 45, new Object());

    // Note that we still perform argument conversions even for the arguments that
    // are subsequently dropped.
    try {
      transform.invoke("foo", 42l, 45l, new Object());
      fail();
    } catch (WrongMethodTypeException expected) {
    } catch (IllegalArgumentException expected) {
      // TODO(narayan): We currently throw the wrong type of exception here,
      // it's IAE and should be WMTE instead.
    }

    // Check that asType works as expected.
    transform = MethodHandles.dropArguments(delegate, 0, int.class, Object.class);
    transform = transform.asType(MethodType.methodType(void.class,
          new Class<?>[] { short.class, Object.class, String.class, long.class }));
    transform.invokeExact((short) 45, new Object(), "foo", 42l);

    // Invalid argument location, should not be allowed.
    try {
      MethodHandles.dropArguments(delegate, -1, int.class, Object.class);
      fail();
    } catch (IllegalArgumentException expected) {
    }

    // Invalid argument location, should not be allowed.
    try {
      MethodHandles.dropArguments(delegate, 3, int.class, Object.class);
      fail();
    } catch (IllegalArgumentException expected) {
    }

    try {
      MethodHandles.dropArguments(delegate, 1, void.class);
      fail();
    } catch (IllegalArgumentException expected) {
    }
  }

  public static String testCatchException_target(String arg1, long arg2, String exceptionMessage)
      throws Throwable {
    if (exceptionMessage != null) {
      throw new IllegalArgumentException(exceptionMessage);
    }

    System.out.println("Target: Arg1: " + arg1 + ", Arg2: " + arg2);
    return "target";
  }

  public static String testCatchException_handler(IllegalArgumentException iae, String arg1, long arg2,
      String exMsg) {
    System.out.println("Handler: " + iae + ", Arg1: " + arg1 + ", Arg2: " + arg2 + ", ExMsg: " + exMsg);
    return "handler1";
  }

  public static String testCatchException_handler2(IllegalArgumentException iae, String arg1) {
    System.out.println("Handler: " + iae + ", Arg1: " + arg1);
    return "handler2";
  }

  public static void testCatchException() throws Throwable {
    MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
        "testCatchException_target",
        MethodType.methodType(String.class, new Class<?>[] { String.class, long.class, String.class }));

    MethodHandle handler = MethodHandles.lookup().findStatic(Main.class,
        "testCatchException_handler",
        MethodType.methodType(String.class, new Class<?>[] { IllegalArgumentException.class,
            String.class, long.class, String.class }));

    MethodHandle adapter = MethodHandles.catchException(target, IllegalArgumentException.class,
        handler);

    String returnVal = null;

    // These two should end up calling the target always. We're passing a null exception
    // message here, which means the target will not throw.
    returnVal = (String) adapter.invoke("foo", 42, null);
    assertEquals("target", returnVal);
    returnVal = (String) adapter.invokeExact("foo", 42l, (String) null);
    assertEquals("target", returnVal);

    // We're passing a non-null exception message here, which means the target will throw,
    // which in turn means that the handler must be called for the next two invokes.
    returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage");
    assertEquals("handler1", returnVal);
    returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage");
    assertEquals("handler1", returnVal);

    handler = MethodHandles.lookup().findStatic(Main.class,
        "testCatchException_handler2",
        MethodType.methodType(String.class, new Class<?>[] { IllegalArgumentException.class,
            String.class }));
    adapter = MethodHandles.catchException(target, IllegalArgumentException.class, handler);

    returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage");
    assertEquals("handler2", returnVal);
    returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage");
    assertEquals("handler2", returnVal);

    // Test that the type of the invoke doesn't matter. Here we call
    // IllegalArgumentException.toString() on the exception that was thrown by
    // the target.
    handler = MethodHandles.lookup().findVirtual(IllegalArgumentException.class,
        "toString", MethodType.methodType(String.class));
    adapter = MethodHandles.catchException(target, IllegalArgumentException.class, handler);

    returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage");
    assertEquals("java.lang.IllegalArgumentException: exceptionMessage", returnVal);
    returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage2");
    assertEquals("java.lang.IllegalArgumentException: exceptionMessage2", returnVal);

    // Check that asType works as expected.
    adapter = MethodHandles.catchException(target, IllegalArgumentException.class,
        handler);
    adapter = adapter.asType(MethodType.methodType(String.class,
          new Class<?>[] { String.class, int.class, String.class }));
    returnVal = (String) adapter.invokeExact("foo", 42, "exceptionMessage");
    assertEquals("java.lang.IllegalArgumentException: exceptionMessage", returnVal);
  }

  public static boolean testGuardWithTest_test(String arg1, long arg2) {
    return "target".equals(arg1) && 42 == arg2;
  }

  public static String testGuardWithTest_target(String arg1, long arg2, int arg3) {
    System.out.println("target: " + arg1 + ", " + arg2  + ", " + arg3);
    return "target";
  }

  public static String testGuardWithTest_fallback(String arg1, long arg2, int arg3) {
    System.out.println("fallback: " + arg1 + ", " + arg2  + ", " + arg3);
    return "fallback";
  }

  public static void testGuardWithTest() throws Throwable {
    MethodHandle test = MethodHandles.lookup().findStatic(Main.class,
        "testGuardWithTest_test",
        MethodType.methodType(boolean.class, new Class<?>[] { String.class, long.class }));

    final MethodType type = MethodType.methodType(String.class,
        new Class<?>[] { String.class, long.class, int.class });

    final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
        "testGuardWithTest_target", type);
    final MethodHandle fallback = MethodHandles.lookup().findStatic(Main.class,
        "testGuardWithTest_fallback", type);

    MethodHandle adapter = MethodHandles.guardWithTest(test, target, fallback);

    String returnVal = null;

    returnVal = (String) adapter.invoke("target", 42, 56);
    assertEquals("target", returnVal);
    returnVal = (String) adapter.invokeExact("target", 42l, 56);
    assertEquals("target", returnVal);

    returnVal = (String) adapter.invoke("fallback", 42l, 56);
    assertEquals("fallback", returnVal);
    returnVal = (String) adapter.invokeExact("target", 42l, 56);
    assertEquals("target", returnVal);

    // Check that asType works as expected.
    adapter = adapter.asType(MethodType.methodType(String.class,
          new Class<?>[] { String.class, int.class, int.class }));
    returnVal = (String) adapter.invokeExact("target", 42, 56);
    assertEquals("target", returnVal);
  }

  public static void testArrayElementGetter() throws Throwable {
    MethodHandle getter = MethodHandles.arrayElementGetter(int[].class);

    {
      int[] array = new int[1];
      array[0] = 42;
      int value = (int) getter.invoke(array, 0);
      if (value != 42) {
        fail("Unexpected value: " + value);
      }

      try {
        value = (int) getter.invoke(array, -1);
        fail();
      } catch (ArrayIndexOutOfBoundsException expected) {
      }

      try {
        value = (int) getter.invoke(null, -1);
        fail();
      } catch (NullPointerException expected) {
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(long[].class);
      long[] array = new long[1];
      array[0] = 42;
      long value = (long) getter.invoke(array, 0);
      if (value != 42l) {
        fail("Unexpected value: " + value);
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(short[].class);
      short[] array = new short[1];
      array[0] = 42;
      short value = (short) getter.invoke(array, 0);
      if (value != 42l) {
        fail("Unexpected value: " + value);
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(char[].class);
      char[] array = new char[1];
      array[0] = 42;
      char value = (char) getter.invoke(array, 0);
      if (value != 42l) {
        fail("Unexpected value: " + value);
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(byte[].class);
      byte[] array = new byte[1];
      array[0] = (byte) 0x8;
      byte value = (byte) getter.invoke(array, 0);
      if (value != (byte) 0x8) {
        fail("Unexpected value: " + value);
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(boolean[].class);
      boolean[] array = new boolean[1];
      array[0] = true;
      boolean value = (boolean) getter.invoke(array, 0);
      if (!value) {
        fail("Unexpected value: " + value);
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(float[].class);
      float[] array = new float[1];
      array[0] = 42.0f;
      float value = (float) getter.invoke(array, 0);
      if (value != 42.0f) {
        fail("Unexpected value: " + value);
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(double[].class);
      double[] array = new double[1];
      array[0] = 42.0;
      double value = (double) getter.invoke(array, 0);
      if (value != 42.0) {
        fail("Unexpected value: " + value);
      }
    }

    {
      getter = MethodHandles.arrayElementGetter(String[].class);
      String[] array = new String[3];
      array[0] = "42";
      array[1] = "48";
      array[2] = "54";
      String value = (String) getter.invoke(array, 0);
      assertEquals("42", value);
      value = (String) getter.invoke(array, 1);
      assertEquals("48", value);
      value = (String) getter.invoke(array, 2);
      assertEquals("54", value);
    }
  }

  public static void testArrayElementSetter() throws Throwable {
    MethodHandle setter = MethodHandles.arrayElementSetter(int[].class);

    {
      int[] array = new int[2];
      setter.invoke(array, 0, 42);
      setter.invoke(array, 1, 43);

      if (array[0] != 42) {
        fail("Unexpected value: " + array[0]);
      }
      if (array[1] != 43) {
        fail("Unexpected value: " + array[1]);
      }

      try {
        setter.invoke(array, -1, 42);
        fail();
      } catch (ArrayIndexOutOfBoundsException expected) {
      }

      try {
        setter.invoke(null, 0, 42);
        fail();
      } catch (NullPointerException expected) {
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(long[].class);
      long[] array = new long[1];
      setter.invoke(array, 0, 42l);
      if (array[0] != 42l) {
        fail("Unexpected value: " + array[0]);
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(short[].class);
      short[] array = new short[1];
      setter.invoke(array, 0, (short) 42);
      if (array[0] != 42l) {
        fail("Unexpected value: " + array[0]);
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(char[].class);
      char[] array = new char[1];
      setter.invoke(array, 0, (char) 42);
      if (array[0] != 42) {
        fail("Unexpected value: " + array[0]);
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(byte[].class);
      byte[] array = new byte[1];
      setter.invoke(array, 0, (byte) 0x8);
      if (array[0] != (byte) 0x8) {
        fail("Unexpected value: " + array[0]);
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(boolean[].class);
      boolean[] array = new boolean[1];
      setter.invoke(array, 0, true);
      if (!array[0]) {
        fail("Unexpected value: " + array[0]);
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(float[].class);
      float[] array = new float[1];
      setter.invoke(array, 0, 42.0f);
      if (array[0] != 42.0f) {
        fail("Unexpected value: " + array[0]);
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(double[].class);
      double[] array = new double[1];
      setter.invoke(array, 0, 42.0);
      if (array[0] != 42.0) {
        fail("Unexpected value: " + array[0]);
      }
    }

    {
      setter = MethodHandles.arrayElementSetter(String[].class);
      String[] array = new String[3];
      setter.invoke(array, 0, "42");
      setter.invoke(array, 1, "48");
      setter.invoke(array, 2, "54");
      assertEquals("42", array[0]);
      assertEquals("48", array[1]);
      assertEquals("54", array[2]);
    }
  }

  public static void testIdentity() throws Throwable {
    {
      MethodHandle identity = MethodHandles.identity(boolean.class);
      boolean value = (boolean) identity.invoke(false);
      if (value) {
        fail("Unexpected value: " + value);
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(byte.class);
      byte value = (byte) identity.invoke((byte) 0x8);
      if (value != (byte) 0x8) {
        fail("Unexpected value: " + value);
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(char.class);
      char value = (char) identity.invoke((char) -56);
      if (value != (char) -56) {
        fail("Unexpected value: " + value);
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(short.class);
      short value = (short) identity.invoke((short) -59);
      if (value != (short) -59) {
        fail("Unexpected value: " + Short.toString(value));
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(int.class);
      int value = (int) identity.invoke(52);
      if (value != 52) {
        fail("Unexpected value: " + value);
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(long.class);
      long value = (long) identity.invoke(-76l);
      if (value != (long) -76) {
        fail("Unexpected value: " + value);
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(float.class);
      float value = (float) identity.invoke(56.0f);
      if (value != (float) 56.0f) {
        fail("Unexpected value: " + value);
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(double.class);
      double value = (double) identity.invoke((double) 72.0);
      if (value != (double) 72.0) {
        fail("Unexpected value: " + value);
      }
    }

    {
      MethodHandle identity = MethodHandles.identity(String.class);
      String value = (String) identity.invoke("bazman");
      assertEquals("bazman", value);
    }
  }

  public static void testConstant() throws Throwable {
    // int constants.
    {
      MethodHandle constant = MethodHandles.constant(int.class, 56);
      int value = (int) constant.invoke();
      if (value != 56) {
        fail("Unexpected value: " + value);
      }

      // short constant values are converted to int.
      constant = MethodHandles.constant(int.class, (short) 52);
      value = (int) constant.invoke();
      if (value != 52) {
        fail("Unexpected value: " + value);
      }

      // char constant values are converted to int.
      constant = MethodHandles.constant(int.class, (char) 'b');
      value = (int) constant.invoke();
      if (value != (int) 'b') {
        fail("Unexpected value: " + value);
      }

      // int constant values are converted to int.
      constant = MethodHandles.constant(int.class, (byte) 0x1);
      value = (int) constant.invoke();
      if (value != 1) {
        fail("Unexpected value: " + value);
      }

      // boolean, float, double and long primitive constants are not convertible
      // to int, so the handle creation must fail with a CCE.
      try {
        MethodHandles.constant(int.class, false);
        fail();
      } catch (ClassCastException expected) {
      }

      try {
        MethodHandles.constant(int.class, 0.1f);
        fail();
      } catch (ClassCastException expected) {
      }

      try {
        MethodHandles.constant(int.class, 0.2);
        fail();
      } catch (ClassCastException expected) {
      }

      try {
        MethodHandles.constant(int.class, 73l);
        fail();
      } catch (ClassCastException expected) {
      }
    }

    // long constants.
    {
      MethodHandle constant = MethodHandles.constant(long.class, 56l);
      long value = (long) constant.invoke();
      if (value != 56l) {
        fail("Unexpected value: " + value);
      }

      constant = MethodHandles.constant(long.class, (int) 56);
      value = (long) constant.invoke();
      if (value != 56l) {
        fail("Unexpected value: " + value);
      }
    }

    // byte constants.
    {
      MethodHandle constant = MethodHandles.constant(byte.class, (byte) 0x12);
      byte value = (byte) constant.invoke();
      if (value != (byte) 0x12) {
        fail("Unexpected value: " + value);
      }
    }

    // boolean constants.
    {
      MethodHandle constant = MethodHandles.constant(boolean.class, true);
      boolean value = (boolean) constant.invoke();
      if (!value) {
        fail("Unexpected value: " + value);
      }
    }

    // char constants.
    {
      MethodHandle constant = MethodHandles.constant(char.class, 'f');
      char value = (char) constant.invoke();
      if (value != 'f') {
        fail("Unexpected value: " + value);
      }
    }

    // short constants.
    {
      MethodHandle constant = MethodHandles.constant(short.class, (short) 123);
      short value = (short) constant.invoke();
      if (value != (short) 123) {
        fail("Unexpected value: " + value);
      }
    }

    // float constants.
    {
      MethodHandle constant = MethodHandles.constant(float.class, 56.0f);
      float value = (float) constant.invoke();
      if (value != 56.0f) {
        fail("Unexpected value: " + value);
      }
    }

    // double constants.
    {
      MethodHandle constant = MethodHandles.constant(double.class, 256.0);
      double value = (double) constant.invoke();
      if (value != 256.0) {
        fail("Unexpected value: " + value);
      }
    }

    // reference constants.
    {
      MethodHandle constant = MethodHandles.constant(String.class, "256.0");
      String value = (String) constant.invoke();
      assertEquals("256.0", value);
    }
  }

  public static void testBindTo() throws Throwable {
    MethodHandle stringCharAt = MethodHandles.lookup().findVirtual(
        String.class, "charAt", MethodType.methodType(char.class, int.class));

    char value = (char) stringCharAt.invoke("foo", 0);
    if (value != 'f') {
      fail("Unexpected value: " + value);
    }

    MethodHandle bound = stringCharAt.bindTo("foo");
    value = (char) bound.invoke(0);
    if (value != 'f') {
      fail("Unexpected value: " + value);
    }

    try {
      stringCharAt.bindTo(new Object());
      fail();
    } catch (ClassCastException expected) {
    }

    bound = stringCharAt.bindTo(null);
    try {
      bound.invoke(0);
      fail();
    } catch (NullPointerException expected) {
    }

    MethodHandle integerParseInt = MethodHandles.lookup().findStatic(
        Integer.class, "parseInt", MethodType.methodType(int.class, String.class));

    bound = integerParseInt.bindTo("78452");
    int intValue = (int) bound.invoke();
    if (intValue != 78452) {
      fail("Unexpected value: " + intValue);
    }
  }

  public static String filterReturnValue_target(int a) {
    return "ReturnValue" + a;
  }

  public static boolean filterReturnValue_filter(String value) {
    return value.indexOf("42") != -1;
  }

  public static int filterReturnValue_intTarget(String a) {
    return Integer.parseInt(a);
  }

  public static int filterReturnValue_intFilter(int b) {
    return b + 1;
  }

  public static void filterReturnValue_voidTarget() {
  }

  public static int filterReturnValue_voidFilter() {
    return 42;
  }

  public static void testFilterReturnValue() throws Throwable {
    // A target that returns a reference.
    {
      final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
          "filterReturnValue_target", MethodType.methodType(String.class, int.class));
      final MethodHandle filter = MethodHandles.lookup().findStatic(Main.class,
          "filterReturnValue_filter", MethodType.methodType(boolean.class, String.class));

      MethodHandle adapter = MethodHandles.filterReturnValue(target, filter);

      boolean value = (boolean) adapter.invoke((int) 42);
      if (!value) {
        fail("Unexpected value: " + value);
      }
      value = (boolean) adapter.invoke((int) 43);
      if (value) {
        fail("Unexpected value: " + value);
      }
    }

    // A target that returns a primitive.
    {
      final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
          "filterReturnValue_intTarget", MethodType.methodType(int.class, String.class));
      final MethodHandle filter = MethodHandles.lookup().findStatic(Main.class,
          "filterReturnValue_intFilter", MethodType.methodType(int.class, int.class));

      MethodHandle adapter = MethodHandles.filterReturnValue(target, filter);

      int value = (int) adapter.invoke("56");
      if (value != 57) {
        fail("Unexpected value: " + value);
      }
    }

    // A target that returns void.
    {
      final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
          "filterReturnValue_voidTarget", MethodType.methodType(void.class));
      final MethodHandle filter = MethodHandles.lookup().findStatic(Main.class,
          "filterReturnValue_voidFilter", MethodType.methodType(int.class));

      MethodHandle adapter = MethodHandles.filterReturnValue(target, filter);

      int value = (int) adapter.invoke();
      if (value != 42) {
        fail("Unexpected value: " + value);
      }
    }
  }

  public static void permuteArguments_callee(boolean a, byte b, char c,
      short d, int e, long f, float g, double h) {
    if (a == true && b == (byte) 'b' && c == 'c' && d == (short) 56 &&
        e == 78 && f == (long) 97 && g == 98.0f && f == 97.0) {
      return;
    }

    fail("Unexpected arguments: " + a + ", " + b + ", " + c
        + ", " + d + ", " + e + ", " + f + ", " + g + ", " + h);
  }

  public static void permuteArguments_boxingCallee(boolean a, Integer b) {
    if (a && b.intValue() == 42) {
      return;
    }

    fail("Unexpected arguments: " + a + ", " + b);
  }

  public static void testPermuteArguments() throws Throwable {
    {
      final MethodHandle target = MethodHandles.lookup().findStatic(
          Main.class, "permuteArguments_callee",
          MethodType.methodType(void.class, new Class<?>[] {
            boolean.class, byte.class, char.class, short.class, int.class,
            long.class, float.class, double.class }));

      final MethodType newType = MethodType.methodType(void.class, new Class<?>[] {
        double.class, float.class, long.class, int.class, short.class, char.class,
        byte.class, boolean.class });

      final MethodHandle permutation = MethodHandles.permuteArguments(
          target, newType, new int[] { 7, 6, 5, 4, 3, 2, 1, 0 });

      permutation.invoke((double) 97.0, (float) 98.0f, (long) 97, 78,
          (short) 56, 'c', (byte) 'b', (boolean) true);

      // The permutation array was not of the right length.
      try {
        MethodHandles.permuteArguments(target, newType,
            new int[] { 7 });
        fail();
      } catch (IllegalArgumentException expected) {
      }

      // The permutation array has an element that's out of bounds
      // (there's no argument with idx == 8).
      try {
        MethodHandles.permuteArguments(target, newType,
            new int[] { 8, 6, 5, 4, 3, 2, 1, 0 });
        fail();
      } catch (IllegalArgumentException expected) {
      }

      // The permutation array maps to an incorrect type.
      try {
        MethodHandles.permuteArguments(target, newType,
            new int[] { 7, 7, 5, 4, 3, 2, 1, 0 });
        fail();
      } catch (IllegalArgumentException expected) {
      }
    }

    // Tests for reference arguments as well as permutations that
    // repeat arguments.
    {
      final MethodHandle target = MethodHandles.lookup().findVirtual(
          String.class, "concat", MethodType.methodType(String.class, String.class));

      final MethodType newType = MethodType.methodType(String.class, String.class,
          String.class);

      assertEquals("foobar", (String) target.invoke("foo", "bar"));

      MethodHandle permutation = MethodHandles.permuteArguments(target,
          newType, new int[] { 1, 0 });
      assertEquals("barfoo", (String) permutation.invoke("foo", "bar"));

      permutation = MethodHandles.permuteArguments(target, newType, new int[] { 0, 0 });
      assertEquals("foofoo", (String) permutation.invoke("foo", "bar"));

      permutation = MethodHandles.permuteArguments(target, newType, new int[] { 1, 1 });
      assertEquals("barbar", (String) permutation.invoke("foo", "bar"));
    }

    // Tests for boxing and unboxing.
    {
      final MethodHandle target = MethodHandles.lookup().findStatic(
          Main.class, "permuteArguments_boxingCallee",
          MethodType.methodType(void.class, new Class<?>[] { boolean.class, Integer.class }));

      final MethodType newType = MethodType.methodType(void.class,
          new Class<?>[] { Integer.class, boolean.class });

      MethodHandle permutation = MethodHandles.permuteArguments(target,
          newType, new int[] { 1, 0 });

      permutation.invoke(42, true);
      permutation.invoke(42, Boolean.TRUE);
      permutation.invoke(Integer.valueOf(42), true);
      permutation.invoke(Integer.valueOf(42), Boolean.TRUE);
    }
  }

  private static Object returnBar() {
    return "bar";
  }

  public static void testInvokers() throws Throwable {
    final MethodType targetType = MethodType.methodType(String.class, String.class);
    final MethodHandle target = MethodHandles.lookup().findVirtual(
        String.class, "concat", targetType);

    MethodHandle invoker = MethodHandles.invoker(target.type());
    assertEquals("barbar", (String) invoker.invoke(target, "bar", "bar"));
    assertEquals("barbar", (String) invoker.invoke(target, (Object) returnBar(), "bar"));
    try {
      String foo = (String) invoker.invoke(target, "bar", "bar", 24);
      fail();
    } catch (WrongMethodTypeException expected) {
    }

    MethodHandle exactInvoker = MethodHandles.exactInvoker(target.type());
    assertEquals("barbar", (String) exactInvoker.invoke(target, "bar", "bar"));
    try {
      String foo = (String) exactInvoker.invoke(target, (Object) returnBar(), "bar");
      fail();
    } catch (WrongMethodTypeException expected) {
    }
    try {
      String foo = (String) exactInvoker.invoke(target, "bar", "bar", 24);
      fail();
    } catch (WrongMethodTypeException expected) {
    }
  }

  public static int spreadReferences(String a, String b, String c) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c);
    return 42;
  }

  public static int spreadReferences_Unbox(String a, int b) {
    System.out.println("a: " + a + ", b:" + b);
    return 43;
  }

  public static void testSpreaders_reference() throws Throwable {
    MethodType methodType = MethodType.methodType(int.class,
        new Class<?>[] { String.class, String.class, String.class });
    MethodHandle delegate = MethodHandles.lookup().findStatic(
        Main.class, "spreadReferences", methodType);

    // Basic checks on array lengths.
    //
    // Array size = 0
    MethodHandle mhAsSpreader = delegate.asSpreader(String[].class, 0);
    int ret = (int) mhAsSpreader.invoke("a", "b", "c", new String[] {});
    assertEquals(42, ret);
    // Array size = 1
    mhAsSpreader = delegate.asSpreader(String[].class, 1);
    ret = (int) mhAsSpreader.invoke("a", "b", new String[] { "c" });
    assertEquals(42, ret);
    // Array size = 2
    mhAsSpreader = delegate.asSpreader(String[].class, 2);
    ret = (int) mhAsSpreader.invoke("a", new String[] { "b", "c" });
    assertEquals(42, ret);
    // Array size = 3
    mhAsSpreader = delegate.asSpreader(String[].class, 3);
    ret = (int) mhAsSpreader.invoke(new String[] { "a", "b", "c"});
    assertEquals(42, ret);

    // Exception case, array size = 4 is illegal.
    try {
      delegate.asSpreader(String[].class, 4);
      fail();
    } catch (IllegalArgumentException expected) {
    }

    // Exception case, calling with an arg of the wrong size.
    // Array size = 3
    mhAsSpreader = delegate.asSpreader(String[].class, 3);
    try {
      ret = (int) mhAsSpreader.invoke(new String[] { "a", "b"});
    } catch (IllegalArgumentException expected) {
    }

    // Various other hijinks, pass as Object[] arrays, Object etc.
    mhAsSpreader = delegate.asSpreader(Object[].class, 2);
    ret = (int) mhAsSpreader.invoke("a", new String[] { "b", "c" });
    assertEquals(42, ret);

    mhAsSpreader = delegate.asSpreader(Object[].class, 2);
    ret = (int) mhAsSpreader.invoke("a", new Object[] { "b", "c" });
    assertEquals(42, ret);

    mhAsSpreader = delegate.asSpreader(Object[].class, 2);
    ret = (int) mhAsSpreader.invoke("a", (Object) new Object[] { "b", "c" });
    assertEquals(42, ret);

    // Test implicit unboxing.
    MethodType methodType2 = MethodType.methodType(int.class,
        new Class<?>[] { String.class, int.class });
    MethodHandle delegate2 = MethodHandles.lookup().findStatic(
        Main.class, "spreadReferences_Unbox", methodType2);

    // .. with an Integer[] array.
    mhAsSpreader = delegate2.asSpreader(Integer[].class, 1);
    ret = (int) mhAsSpreader.invoke("a", new Integer[] { 43 });
    assertEquals(43, ret);

    // .. with an Integer[] array declared as an Object[] argument type.
    mhAsSpreader = delegate2.asSpreader(Object[].class, 1);
    ret = (int) mhAsSpreader.invoke("a", new Integer[] { 43 });
    assertEquals(43, ret);

    // .. with an Object[] array.
    mhAsSpreader = delegate2.asSpreader(Object[].class, 1);
    ret = (int) mhAsSpreader.invoke("a", new Object[] { Integer.valueOf(43)});
    assertEquals(43, ret);

    // -- Part 2--
    // Run a subset of these tests on MethodHandles.spreadInvoker, which only accepts
    // a trailing argument type of Object[].
    MethodHandle spreadInvoker = MethodHandles.spreadInvoker(methodType2, 1);
    ret = (int) spreadInvoker.invoke(delegate2, "a", new Object[] { Integer.valueOf(43)});
    assertEquals(43, ret);

    ret = (int) spreadInvoker.invoke(delegate2, "a", new Integer[] { 43 });
    assertEquals(43, ret);

    // NOTE: Annoyingly, the second argument here is leadingArgCount and not
    // arrayLength.
    spreadInvoker = MethodHandles.spreadInvoker(methodType, 3);
    ret = (int) spreadInvoker.invoke(delegate, "a", "b", "c", new String[] {});
    assertEquals(42, ret);

    spreadInvoker = MethodHandles.spreadInvoker(methodType, 0);
    ret = (int) spreadInvoker.invoke(delegate, new String[] { "a", "b", "c" });
    assertEquals(42, ret);

    // Exact invokes: Double check that the expected parameter type is
    // Object[] and not T[].
    try {
      spreadInvoker.invokeExact(delegate, new String[] { "a", "b", "c" });
      fail();
    } catch (WrongMethodTypeException expected) {
    }

    ret = (int) spreadInvoker.invoke(delegate, new Object[] { "a", "b", "c" });
    assertEquals(42, ret);
  }

  public static int spreadBoolean(String a, Boolean b, boolean c) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c);
    return 44;
  }

  public static int spreadByte(String a, Byte b, byte c,
      short d, int e, long f, float g, double h) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c +
        ", d: " + d + ", e: " + e + ", f:" + f + ", g: " + g +
        ", h: " + h);
    return 45;
  }

  public static int spreadChar(String a, Character b, char c,
      int d, long e, float f, double g) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c +
        ", d: " + d + ", e: " + e + ", f:" + f + ", g: " + g);
    return 46;
  }

  public static int spreadShort(String a, Short b, short c,
      int d, long e, float f, double g) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c +
        ", d: " + d + ", e: " + e + ", f:" + f + ", g:" + g);
    return 47;
  }

  public static int spreadInt(String a, Integer b, int c,
      long d, float e, double f) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c +
        ", d: " + d + ", e: " + e + ", f:" + f);
    return 48;
  }

  public static int spreadLong(String a, Long b, long c, float d, double e) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c +
        ", d: " + d + ", e: " + e);
    return 49;
  }

  public static int spreadFloat(String a, Float b, float c, double d) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c + ", d: " + d);
    return 50;
  }

  public static int spreadDouble(String a, Double b, double c) {
    System.out.println("a: " + a + ", b:" + b + ", c: " + c);
    return 51;
  }

  public static void testSpreaders_primitive() throws Throwable {
    // boolean[]
    // ---------------------
    MethodType type = MethodType.methodType(int.class,
        new Class<?>[] { String.class, Boolean.class, boolean.class });
    MethodHandle delegate = MethodHandles.lookup().findStatic(
        Main.class, "spreadBoolean", type);

    MethodHandle spreader = delegate.asSpreader(boolean[].class, 2);
    int ret = (int) spreader.invokeExact("a", new boolean[] { true, false });
    assertEquals(44, ret);
    ret = (int) spreader.invoke("a", new boolean[] { true, false });
    assertEquals(44, ret);

    // boolean can't be cast to String (the first argument to the method).
    try {
      delegate.asSpreader(boolean[].class, 3);
      fail();
    } catch (WrongMethodTypeException expected) {
    }

    // int can't be cast to boolean to supply the last argument to the method.
    try {
      delegate.asSpreader(int[].class, 1);
      fail();
    } catch (WrongMethodTypeException expected) {
    }

    // byte[]
    // ---------------------
    type = MethodType.methodType(int.class,
        new Class<?>[] {
          String.class, Byte.class, byte.class,
          short.class, int.class, long.class,
          float.class, double.class });
    delegate = MethodHandles.lookup().findStatic(Main.class, "spreadByte", type);

    spreader = delegate.asSpreader(byte[].class, 7);
    ret = (int) spreader.invokeExact("a",
        new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 });
    assertEquals(45, ret);
    ret = (int) spreader.invoke("a",
        new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 });
    assertEquals(45, ret);

    // char[]
    // ---------------------
    type = MethodType.methodType(int.class,
        new Class<?>[] {
          String.class, Character.class,char.class,
          int.class, long.class, float.class, double.class });
    delegate = MethodHandles.lookup().findStatic(Main.class, "spreadChar", type);

    spreader = delegate.asSpreader(char[].class, 6);
    ret = (int) spreader.invokeExact("a",
        new char[] { '1', '2', '3', '4', '5', '6' });
    assertEquals(46, ret);
    ret = (int) spreader.invokeExact("a",
        new char[] { '1', '2', '3', '4', '5', '6' });
    assertEquals(46, ret);

    // short[]
    // ---------------------
    type = MethodType.methodType(int.class,
        new Class<?>[] {
          String.class, Short.class, short.class,
          int.class, long.class, float.class, double.class });
    delegate = MethodHandles.lookup().findStatic(Main.class, "spreadShort", type);

    spreader = delegate.asSpreader(short[].class, 6);
    ret = (int) spreader.invokeExact("a",
        new short[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 });
    assertEquals(47, ret);
    ret = (int) spreader.invoke("a",
        new short[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 });
    assertEquals(47, ret);

    // int[]
    // ---------------------
    type = MethodType.methodType(int.class,
        new Class<?>[] {
          String.class, Integer.class, int.class,
          long.class, float.class, double.class });
    delegate = MethodHandles.lookup().findStatic(Main.class, "spreadInt", type);

    spreader = delegate.asSpreader(int[].class, 5);
    ret = (int) spreader.invokeExact("a", new int[] { 1, 2, 3, 4, 5 });
    assertEquals(48, ret);
    ret = (int) spreader.invokeExact("a", new int[] { 1, 2, 3, 4, 5 });
    assertEquals(48, ret);

    // long[]
    // ---------------------
    type = MethodType.methodType(int.class,
        new Class<?>[] {
          String.class, Long.class, long.class, float.class, double.class });
    delegate = MethodHandles.lookup().findStatic(Main.class, "spreadLong", type);

    spreader = delegate.asSpreader(long[].class, 4);
    ret = (int) spreader.invokeExact("a",
        new long[] { 0x1, 0x2, 0x3, 0x4 });
    assertEquals(49, ret);
    ret = (int) spreader.invoke("a",
        new long[] { 0x1, 0x2, 0x3, 0x4 });
    assertEquals(49, ret);

    // float[]
    // ---------------------
    type = MethodType.methodType(int.class,
        new Class<?>[] {
          String.class, Float.class, float.class, double.class });
    delegate = MethodHandles.lookup().findStatic(Main.class, "spreadFloat", type);

    spreader = delegate.asSpreader(float[].class, 3);
    ret = (int) spreader.invokeExact("a",
        new float[] { 1.0f, 2.0f, 3.0f });
    assertEquals(50, ret);
    ret = (int) spreader.invokeExact("a",
        new float[] { 1.0f, 2.0f, 3.0f });
    assertEquals(50, ret);

    // double[]
    // ---------------------
    type = MethodType.methodType(int.class,
        new Class<?>[] { String.class, Double.class, double.class });
    delegate = MethodHandles.lookup().findStatic(Main.class, "spreadDouble", type);

    spreader = delegate.asSpreader(double[].class, 2);
    ret = (int) spreader.invokeExact("a", new double[] { 1.0, 2.0 });
    assertEquals(51, ret);
    ret = (int) spreader.invokeExact("a", new double[] { 1.0, 2.0 });
    assertEquals(51, ret);
  }

  public static void fail() {
    System.out.println("FAIL");
    Thread.dumpStack();
  }

  public static void fail(String message) {
    System.out.println("fail: " + message);
    Thread.dumpStack();
  }

  public static void assertEquals(int i1, int i2) {
    if (i1 != i2) throw new AssertionError("Expected: " + i1 + " was " + i2);
  }

  public static void assertEquals(String s1, String s2) {
    if (s1 == s2) {
      return;
    }

    if (s1 != null && s2 != null && s1.equals(s2)) {
      return;
    }

    throw new AssertionError("assertEquals s1: " + s1 + ", s2: " + s2);
  }
}
