Move tests that require java8 into a java8 suite.

Change-Id: Ic69b6c88a80f8e54b7ff979d18c381e2b2e254d6
diff --git a/user/test/com/google/gwt/emultest/EmulJava8Suite.java b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
index fbe0c91..e898b30 100644
--- a/user/test/com/google/gwt/emultest/EmulJava8Suite.java
+++ b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
@@ -15,6 +15,10 @@
  */
 package com.google.gwt.emultest;
 
+import com.google.gwt.emultest.java8.lang.DoubleTest;
+import com.google.gwt.emultest.java8.lang.FloatTest;
+import com.google.gwt.emultest.java8.lang.MathTest;
+import com.google.gwt.emultest.java8.lang.StringTest;
 import com.google.gwt.emultest.java8.math.BigIntegerConvertTest;
 import com.google.gwt.emultest.java8.util.ArrayListTest;
 import com.google.gwt.emultest.java8.util.ArraysTest;
@@ -51,6 +55,12 @@
   public static Test suite() {
     GWTTestSuite suite = new GWTTestSuite("Tests for com.google.gwt.emul.java8");
 
+    //-- java.lang
+    suite.addTestSuite(DoubleTest.class);
+    suite.addTestSuite(FloatTest.class);
+    suite.addTestSuite(MathTest.class);
+    suite.addTestSuite(StringTest.class);
+
     //-- java.math
     suite.addTestSuite(BigIntegerConvertTest.class);
 
diff --git a/user/test/com/google/gwt/emultest/java/lang/DoubleTest.java b/user/test/com/google/gwt/emultest/java/lang/DoubleTest.java
index 8d84e2d..65d961f 100644
--- a/user/test/com/google/gwt/emultest/java/lang/DoubleTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/DoubleTest.java
@@ -164,23 +164,6 @@
     assertFalse(Double.isInfinite(Double.NaN));
   }
 
-  public void testIsFinite() {
-    final double[] nonfiniteNumbers = {
-        Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN,
-    };
-    for (double value : nonfiniteNumbers) {
-      assertFalse(Double.isFinite(value));
-    }
-
-    final double[] finiteNumbers = {
-        -Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE,
-        -1.0, -0.5, -0.1, -0.0, 0.0, 0.1, 0.5, 1.0,
-    };
-    for (double value : finiteNumbers) {
-      assertTrue(Double.isFinite(value));
-    }
-  }
-
   public void testIsInfinite() {
     assertTrue(Double.isInfinite(Double.NEGATIVE_INFINITY));
     assertTrue(Double.isInfinite(Double.POSITIVE_INFINITY));
diff --git a/user/test/com/google/gwt/emultest/java/lang/FloatTest.java b/user/test/com/google/gwt/emultest/java/lang/FloatTest.java
index 87dc276..f12efcd 100644
--- a/user/test/com/google/gwt/emultest/java/lang/FloatTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/FloatTest.java
@@ -97,38 +97,6 @@
     assertFalse(Float.isInfinite(Float.NaN));
   }
 
-  public void testIsFinite() {
-    final float[] nonfiniteNumbers = {
-        Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN,
-    };
-    for (float value : nonfiniteNumbers) {
-      assertFalse(Float.isFinite(value));
-    }
-
-    final float[] finiteNumbers = {
-        -Float.MAX_VALUE, Float.MAX_VALUE, Float.MIN_VALUE,
-        -1.0f, -0.5f, -0.1f, -0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
-    };
-    for (float value : finiteNumbers) {
-      assertTrue(Float.isFinite(value));
-    }
-  }
-
-  public void testIsInfinite() {
-    assertTrue(Float.isInfinite(Float.NEGATIVE_INFINITY));
-    assertTrue(Float.isInfinite(Float.POSITIVE_INFINITY));
-
-    assertFalse(Float.isInfinite(Float.NaN));
-
-    final float[] finiteNumbers = {
-        -Float.MAX_VALUE, Float.MAX_VALUE, Float.MIN_VALUE,
-        -1.0f, -0.5f, -0.1f, -0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
-    };
-    for (float value : finiteNumbers) {
-      assertFalse(Float.isInfinite(value));
-    }
-  }
-
   public void testParse() {
     /*
      * Note: we must use appropriate deltas for a somewhat subtle reason.
diff --git a/user/test/com/google/gwt/emultest/java/lang/MathTest.java b/user/test/com/google/gwt/emultest/java/lang/MathTest.java
index 084da67..3128b81 100644
--- a/user/test/com/google/gwt/emultest/java/lang/MathTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/MathTest.java
@@ -18,9 +18,6 @@
 
 import com.google.gwt.junit.client.GWTTestCase;
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-
 /**
  * Tests for JRE emulation of java.lang.Math.
  *
@@ -28,9 +25,6 @@
  */
 public class MathTest extends GWTTestCase {
 
-  private static final Integer[] ALL_INTEGER_CANDIDATES = getAllIntegerCandidates();
-  private static final Long[] ALL_LONG_CANDIDATES = getAllLongCandidates();
-
   private static void assertNegativeZero(double x) {
     assertTrue(isNegativeZero(x));
   }
@@ -80,36 +74,6 @@
     assertNaN(v);
   }
 
-  public void testAddExact() {
-    for (int a : ALL_INTEGER_CANDIDATES) {
-      for (int b : ALL_INTEGER_CANDIDATES) {
-        BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.valueOf(b));
-        boolean expectedSuccess = fitsInInt(expectedResult);
-        try {
-          assertEquals(a + b, Math.addExact(a, b));
-          assertTrue(expectedSuccess);
-        } catch (ArithmeticException e) {
-          assertFalse(expectedSuccess);
-        }
-      }
-    }
-  }
-
-  public void testAddExactLongs() {
-    for (long a : ALL_LONG_CANDIDATES) {
-      for (long b : ALL_LONG_CANDIDATES) {
-        BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.valueOf(b));
-        boolean expectedSuccess = fitsInLong(expectedResult);
-        try {
-          assertEquals(a + b, Math.addExact(a, b));
-          assertTrue(expectedSuccess);
-        } catch (ArithmeticException e) {
-          assertFalse(expectedSuccess);
-        }
-      }
-    }
-  }
-
   public void testCbrt() {
     double v = Math.cbrt(1000.0);
     assertEquals(10.0, v, 1e-7);
@@ -184,32 +148,6 @@
     assertEquals(Double.POSITIVE_INFINITY, v);
   }
 
-  public void testDecrementExact() {
-    for (int a : ALL_INTEGER_CANDIDATES) {
-      BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.ONE);
-      boolean expectedSuccess = fitsInInt(expectedResult);
-      try {
-        assertEquals(a - 1, Math.decrementExact(a));
-        assertTrue(expectedSuccess);
-      } catch (ArithmeticException e) {
-        assertFalse(expectedSuccess);
-      }
-    }
-  }
-
-  public void testDecrementExactLong() {
-    for (long a : ALL_LONG_CANDIDATES) {
-      BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.ONE);
-      boolean expectedSuccess = fitsInLong(expectedResult);
-      try {
-        assertEquals(a - 1, Math.decrementExact(a));
-        assertTrue(expectedSuccess);
-      } catch (ArithmeticException e) {
-        assertFalse(expectedSuccess);
-      }
-    }
-  }
-
   public void testExpm1() {
     assertNegativeZero(Math.expm1(-0.));
     assertPositiveZero(Math.expm1(0.));
@@ -236,110 +174,6 @@
     assertEquals(-Double.MAX_VALUE, v, 0);
   }
 
-  public void testFloorDiv() {
-    assertEquals(0, Math.floorDiv(0, 1));
-    assertEquals(1, Math.floorDiv(4, 3));
-    assertEquals(-2, Math.floorDiv(4, -3));
-    assertEquals(-2, Math.floorDiv(-4, 3));
-    assertEquals(1, Math.floorDiv(-4, -3));
-    assertEquals(1, Math.floorDiv(Integer.MIN_VALUE, Integer.MIN_VALUE));
-    assertEquals(1, Math.floorDiv(Integer.MAX_VALUE, Integer.MAX_VALUE));
-    assertEquals(Integer.MIN_VALUE, Math.floorDiv(Integer.MIN_VALUE, 1));
-    assertEquals(Integer.MAX_VALUE, Math.floorDiv(Integer.MAX_VALUE, 1));
-
-    // special case
-    assertEquals(Integer.MIN_VALUE, Math.floorDiv(Integer.MIN_VALUE, -1));
-
-    try {
-      Math.floorDiv(1, 0);
-      fail();
-    } catch (ArithmeticException expected) {
-    }
-  }
-
-  public void testFloorDivLongs() {
-    assertEquals(0L, Math.floorDiv(0L, 1L));
-    assertEquals(1L, Math.floorDiv(4L, 3L));
-    assertEquals(-2L, Math.floorDiv(4L, -3L));
-    assertEquals(-2L, Math.floorDiv(-4L, 3L));
-    assertEquals(1L, Math.floorDiv(-4L, -3L));
-    assertEquals(1L, Math.floorDiv(Long.MIN_VALUE, Long.MIN_VALUE));
-    assertEquals(1L, Math.floorDiv(Long.MAX_VALUE, Long.MAX_VALUE));
-    assertEquals(Long.MIN_VALUE, Math.floorDiv(Long.MIN_VALUE, 1L));
-    assertEquals(Long.MAX_VALUE, Math.floorDiv(Long.MAX_VALUE, 1L));
-
-    // special case
-    assertEquals(Long.MIN_VALUE, Math.floorDiv(Long.MIN_VALUE, -1));
-
-    try {
-      Math.floorDiv(1L, 0L);
-      fail();
-    } catch (ArithmeticException expected) {
-    }
-  }
-
-  public void testFloorMod() {
-    assertEquals(0, Math.floorMod(0, 1));
-    assertEquals(1, Math.floorMod(4, 3));
-    assertEquals(-2, Math.floorMod(4, -3));
-    assertEquals(2, Math.floorMod(-4, 3));
-    assertEquals(-1, Math.floorMod(-4, -3));
-    assertEquals(0, Math.floorMod(Integer.MIN_VALUE, Integer.MIN_VALUE));
-    assertEquals(0, Math.floorMod(Integer.MAX_VALUE, Integer.MAX_VALUE));
-    assertEquals(0, Math.floorMod(Integer.MIN_VALUE, 1));
-    assertEquals(0, Math.floorMod(Integer.MAX_VALUE, 1));
-
-    try {
-      Math.floorMod(1, 0);
-      fail();
-    } catch (ArithmeticException expected) {
-    }
-  }
-
-  public void testFloorModLongs() {
-    assertEquals(0L, Math.floorMod(0L, 1L));
-    assertEquals(1L, Math.floorMod(4L, 3L));
-    assertEquals(-2L, Math.floorMod(4L, -3L));
-    assertEquals(2L, Math.floorMod(-4L, 3L));
-    assertEquals(-1L, Math.floorMod(-4L, -3L));
-    assertEquals(0L, Math.floorMod(Long.MIN_VALUE, Long.MIN_VALUE));
-    assertEquals(0L, Math.floorMod(Long.MAX_VALUE, Long.MAX_VALUE));
-    assertEquals(0L, Math.floorMod(Long.MIN_VALUE, 1L));
-    assertEquals(0L, Math.floorMod(Long.MAX_VALUE, 1L));
-
-    try {
-      Math.floorMod(1L, 0L);
-      fail();
-    } catch (ArithmeticException expected) {
-    }
-  }
-
-  public void testIncrementExact() {
-    for (int a : ALL_INTEGER_CANDIDATES) {
-      BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.ONE);
-      boolean expectedSuccess = fitsInInt(expectedResult);
-      try {
-        assertEquals(a + 1, Math.incrementExact(a));
-        assertTrue(expectedSuccess);
-      } catch (ArithmeticException e) {
-        assertFalse(expectedSuccess);
-      }
-    }
-  }
-
-  public void testIncrementExactLong() {
-    for (long a : ALL_LONG_CANDIDATES) {
-      BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.ONE);
-      boolean expectedSuccess = fitsInLong(expectedResult);
-      try {
-        assertEquals(a + 1, Math.incrementExact(a));
-        assertTrue(expectedSuccess);
-      } catch (ArithmeticException e) {
-        assertFalse(expectedSuccess);
-      }
-    }
-  }
-
   public void testMax() {
     assertEquals(2d, Math.max(1d, 2d));
     assertEquals(2d, Math.max(2d, 1d));
@@ -414,62 +248,6 @@
     assertEquals(3.0, v, 1e-15);
   }
 
-  public void testMultiplyExact() {
-    for (int a : ALL_INTEGER_CANDIDATES) {
-      for (int b : ALL_INTEGER_CANDIDATES) {
-        BigInteger expectedResult = BigInteger.valueOf(a).multiply(BigInteger.valueOf(b));
-        boolean expectedSuccess = fitsInInt(expectedResult);
-        try {
-          assertEquals(a * b, Math.multiplyExact(a, b));
-          assertTrue(expectedSuccess);
-        } catch (ArithmeticException e) {
-          assertFalse(expectedSuccess);
-        }
-      }
-    }
-  }
-
-  public void testMultiplyExactLongs() {
-    for (long a : ALL_LONG_CANDIDATES) {
-      for (long b : ALL_LONG_CANDIDATES) {
-        BigInteger expectedResult = BigInteger.valueOf(a).multiply(BigInteger.valueOf(b));
-        boolean expectedSuccess = fitsInLong(expectedResult);
-        try {
-          assertEquals(a * b, Math.multiplyExact(a, b));
-          assertTrue(expectedSuccess);
-        } catch (ArithmeticException e) {
-          assertFalse(expectedSuccess);
-        }
-      }
-    }
-  }
-
-  public void testNegateExact() {
-    for (int a : ALL_INTEGER_CANDIDATES) {
-      BigInteger expectedResult = BigInteger.valueOf(a).negate();
-      boolean expectedSuccess = fitsInInt(expectedResult);
-      try {
-        assertEquals(-a, Math.negateExact(a));
-        assertTrue(expectedSuccess);
-      } catch (ArithmeticException e) {
-        assertFalse(expectedSuccess);
-      }
-    }
-  }
-
-  public void testNegateExactLong() {
-    for (long a : ALL_LONG_CANDIDATES) {
-      BigInteger expectedResult = BigInteger.valueOf(a).negate();
-      boolean expectedSuccess = fitsInLong(expectedResult);
-      try {
-        assertEquals(-a, Math.negateExact(a));
-        assertTrue(expectedSuccess);
-      } catch (ArithmeticException e) {
-        assertFalse(expectedSuccess);
-      }
-    }
-  }
-
   public void testRound() {
     long v = Math.round(0.5);
     assertEquals(1L, v);
@@ -625,97 +403,4 @@
     assertEquals(4294967296.0f, Math.scalb(1f, 32));
     assertEquals(2.3283064e-10f, Math.scalb(1f, -32), 1e-7f);
   }
-
-  public void testSubtractExact() {
-    for (int a : ALL_INTEGER_CANDIDATES) {
-      for (int b : ALL_INTEGER_CANDIDATES) {
-        BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.valueOf(b));
-        boolean expectedSuccess = fitsInInt(expectedResult);
-        try {
-          assertEquals(a - b, Math.subtractExact(a, b));
-          assertTrue(expectedSuccess);
-        } catch (ArithmeticException e) {
-          assertFalse(expectedSuccess);
-        }
-      }
-    }
-  }
-
-  public void testSubtractExactLongs() {
-    for (long a : ALL_LONG_CANDIDATES) {
-      for (long b : ALL_LONG_CANDIDATES) {
-        BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.valueOf(b));
-        boolean expectedSuccess = fitsInLong(expectedResult);
-        try {
-          assertEquals(a - b, Math.subtractExact(a, b));
-          assertTrue(expectedSuccess);
-        } catch (ArithmeticException e) {
-          assertFalse(expectedSuccess);
-        }
-      }
-    }
-  }
-
-  public void testToIntExact() {
-    final long[] longs = {0, -1, 1, Integer.MIN_VALUE, Integer.MAX_VALUE,
-        Integer.MIN_VALUE - 1L, Integer.MAX_VALUE + 1L, Long.MIN_VALUE, Long.MAX_VALUE};
-    for (long a : longs) {
-      boolean expectedSuccess = (int) a == a;
-      try {
-        assertEquals((int) a, Math.toIntExact(a));
-        assertTrue(expectedSuccess);
-      } catch (ArithmeticException e) {
-        assertFalse(expectedSuccess);
-      }
-    }
-  }
-
-  private static boolean fitsInInt(BigInteger big) {
-    return big.bitLength() < Integer.SIZE;
-  }
-
-  private static boolean fitsInLong(BigInteger big) {
-    return big.bitLength() < Long.SIZE;
-  }
-
-  private static Integer[] getAllIntegerCandidates() {
-    ArrayList<Integer> candidates = new ArrayList<Integer>();
-    candidates.add(0);
-    candidates.add(-1);
-    candidates.add(1);
-    candidates.add(Integer.MAX_VALUE / 2);
-    candidates.add(Integer.MAX_VALUE / 2 - 1);
-    candidates.add(Integer.MAX_VALUE / 2 + 1);
-    candidates.add(Integer.MIN_VALUE / 2);
-    candidates.add(Integer.MIN_VALUE / 2 - 1);
-    candidates.add(Integer.MIN_VALUE / 2 + 1);
-    candidates.add(Integer.MAX_VALUE - 1);
-    candidates.add(Integer.MAX_VALUE);
-    candidates.add(Integer.MIN_VALUE + 1);
-    candidates.add(Integer.MIN_VALUE);
-    return candidates.toArray(new Integer[candidates.size()]);
-  }
-
-  private static Long[] getAllLongCandidates() {
-    ArrayList<Long> candidates = new ArrayList<Long>();
-
-    for (Integer x : getAllIntegerCandidates()) {
-      candidates.add(x.longValue());
-    }
-
-    candidates.add(Long.MAX_VALUE / 2);
-    candidates.add(Long.MAX_VALUE / 2 - 1);
-    candidates.add(Long.MAX_VALUE / 2 + 1);
-    candidates.add(Long.MIN_VALUE / 2);
-    candidates.add(Long.MIN_VALUE / 2 - 1);
-    candidates.add(Long.MIN_VALUE / 2 + 1);
-    candidates.add(Integer.MAX_VALUE + 1L);
-    candidates.add(Long.MAX_VALUE - 1L);
-    candidates.add(Long.MAX_VALUE);
-    candidates.add(Integer.MIN_VALUE - 1L);
-    candidates.add(Long.MIN_VALUE + 1L);
-    candidates.add(Long.MIN_VALUE);
-
-    return candidates.toArray(new Long[candidates.size()]);
-  }
 }
diff --git a/user/test/com/google/gwt/emultest/java/lang/StringTest.java b/user/test/com/google/gwt/emultest/java/lang/StringTest.java
index e897f9d..b9f06aa 100644
--- a/user/test/com/google/gwt/emultest/java/lang/StringTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/StringTest.java
@@ -20,7 +20,6 @@
 
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
-import java.util.Arrays;
 import java.util.Locale;
 
 /**
@@ -461,24 +460,6 @@
     assertSame("interns are not the same reference", s1.intern(), s2.intern());
   }
 
-  public void testJoin() {
-    assertEquals("", String.join("", ""));
-    assertEquals("", String.join(",", ""));
-    assertEquals("", String.join(",", Arrays.<String>asList()));
-
-    assertEquals("a", String.join("", "a"));
-    assertEquals("a", String.join(",", "a"));
-    assertEquals("a", String.join(",", Arrays.asList("a")));
-
-    assertEquals("ab", String.join("", "a", "b"));
-    assertEquals("a,b", String.join(",", "a", "b"));
-    assertEquals("a,b", String.join(",", Arrays.asList("a", "b")));
-
-    assertEquals("abc", String.join("", "a", "b", "c"));
-    assertEquals("a,b,c", String.join(",", "a", "b", "c"));
-    assertEquals("a,b,c", String.join(",", Arrays.asList("a", "b", "c")));
-  }
-
   public void testLastIndexOf() {
     String x = "abcdeabcdef";
     assertEquals(9, x.lastIndexOf("e"));
diff --git a/user/test/com/google/gwt/emultest/java8/lang/DoubleTest.java b/user/test/com/google/gwt/emultest/java8/lang/DoubleTest.java
new file mode 100644
index 0000000..677dd20
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/lang/DoubleTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * 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.
+ */
+
+package com.google.gwt.emultest.java8.lang;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Unit tests for the emulated-in-Javascript Double/double autoboxed types.
+ */
+public class DoubleTest extends GWTTestCase {
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.emultest.EmulSuite";
+  }
+
+  public void testIsFinite() {
+    final double[] nonfiniteNumbers = {
+        Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN,
+    };
+    for (double value : nonfiniteNumbers) {
+      assertFalse(Double.isFinite(value));
+    }
+
+    final double[] finiteNumbers = {
+        -Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE,
+        -1.0, -0.5, -0.1, -0.0, 0.0, 0.1, 0.5, 1.0,
+    };
+    for (double value : finiteNumbers) {
+      assertTrue(Double.isFinite(value));
+    }
+  }
+}
+
diff --git a/user/test/com/google/gwt/emultest/java8/lang/FloatTest.java b/user/test/com/google/gwt/emultest/java8/lang/FloatTest.java
new file mode 100644
index 0000000..b130eae
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/lang/FloatTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * 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.
+ */
+
+package com.google.gwt.emultest.java8.lang;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Unit tests for the Javascript emulation of the Float/float autoboxed
+ * fundamental type.
+ */
+public class FloatTest extends GWTTestCase {
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.emultest.EmulSuite";
+  }
+
+  public void testIsFinite() {
+    final float[] nonfiniteNumbers = {
+        Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN,
+    };
+    for (float value : nonfiniteNumbers) {
+      assertFalse(Float.isFinite(value));
+    }
+
+    final float[] finiteNumbers = {
+        -Float.MAX_VALUE, Float.MAX_VALUE, Float.MIN_VALUE,
+        -1.0f, -0.5f, -0.1f, -0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
+    };
+    for (float value : finiteNumbers) {
+      assertTrue(Float.isFinite(value));
+    }
+  }
+
+  public void testIsInfinite() {
+    assertTrue(Float.isInfinite(Float.NEGATIVE_INFINITY));
+    assertTrue(Float.isInfinite(Float.POSITIVE_INFINITY));
+
+    assertFalse(Float.isInfinite(Float.NaN));
+
+    final float[] finiteNumbers = {
+        -Float.MAX_VALUE, Float.MAX_VALUE, Float.MIN_VALUE,
+        -1.0f, -0.5f, -0.1f, -0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
+    };
+    for (float value : finiteNumbers) {
+      assertFalse(Float.isInfinite(value));
+    }
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java8/lang/MathTest.java b/user/test/com/google/gwt/emultest/java8/lang/MathTest.java
new file mode 100644
index 0000000..5b6f914
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/lang/MathTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * 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.
+ */
+
+package com.google.gwt.emultest.java8.lang;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+
+/**
+ * Tests for JRE emulation of java.lang.Math.
+ */
+public class MathTest extends GWTTestCase {
+
+  private static final Integer[] ALL_INTEGER_CANDIDATES = getAllIntegerCandidates();
+  private static final Long[] ALL_LONG_CANDIDATES = getAllLongCandidates();
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.emultest.EmulSuite";
+  }
+
+  public void testAddExact() {
+    for (int a : ALL_INTEGER_CANDIDATES) {
+      for (int b : ALL_INTEGER_CANDIDATES) {
+        BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.valueOf(b));
+        boolean expectedSuccess = fitsInInt(expectedResult);
+        try {
+          assertEquals(a + b, Math.addExact(a, b));
+          assertTrue(expectedSuccess);
+        } catch (ArithmeticException e) {
+          assertFalse(expectedSuccess);
+        }
+      }
+    }
+  }
+
+  public void testAddExactLongs() {
+    for (long a : ALL_LONG_CANDIDATES) {
+      for (long b : ALL_LONG_CANDIDATES) {
+        BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.valueOf(b));
+        boolean expectedSuccess = fitsInLong(expectedResult);
+        try {
+          assertEquals(a + b, Math.addExact(a, b));
+          assertTrue(expectedSuccess);
+        } catch (ArithmeticException e) {
+          assertFalse(expectedSuccess);
+        }
+      }
+    }
+  }
+
+  public void testDecrementExact() {
+    for (int a : ALL_INTEGER_CANDIDATES) {
+      BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.ONE);
+      boolean expectedSuccess = fitsInInt(expectedResult);
+      try {
+        assertEquals(a - 1, Math.decrementExact(a));
+        assertTrue(expectedSuccess);
+      } catch (ArithmeticException e) {
+        assertFalse(expectedSuccess);
+      }
+    }
+  }
+
+  public void testDecrementExactLong() {
+    for (long a : ALL_LONG_CANDIDATES) {
+      BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.ONE);
+      boolean expectedSuccess = fitsInLong(expectedResult);
+      try {
+        assertEquals(a - 1, Math.decrementExact(a));
+        assertTrue(expectedSuccess);
+      } catch (ArithmeticException e) {
+        assertFalse(expectedSuccess);
+      }
+    }
+  }
+
+  public void testFloorDiv() {
+    assertEquals(0, Math.floorDiv(0, 1));
+    assertEquals(1, Math.floorDiv(4, 3));
+    assertEquals(-2, Math.floorDiv(4, -3));
+    assertEquals(-2, Math.floorDiv(-4, 3));
+    assertEquals(1, Math.floorDiv(-4, -3));
+    assertEquals(1, Math.floorDiv(Integer.MIN_VALUE, Integer.MIN_VALUE));
+    assertEquals(1, Math.floorDiv(Integer.MAX_VALUE, Integer.MAX_VALUE));
+    assertEquals(Integer.MIN_VALUE, Math.floorDiv(Integer.MIN_VALUE, 1));
+    assertEquals(Integer.MAX_VALUE, Math.floorDiv(Integer.MAX_VALUE, 1));
+
+    // special case
+    assertEquals(Integer.MIN_VALUE, Math.floorDiv(Integer.MIN_VALUE, -1));
+
+    try {
+      Math.floorDiv(1, 0);
+      fail();
+    } catch (ArithmeticException expected) {
+    }
+  }
+
+  public void testFloorDivLongs() {
+    assertEquals(0L, Math.floorDiv(0L, 1L));
+    assertEquals(1L, Math.floorDiv(4L, 3L));
+    assertEquals(-2L, Math.floorDiv(4L, -3L));
+    assertEquals(-2L, Math.floorDiv(-4L, 3L));
+    assertEquals(1L, Math.floorDiv(-4L, -3L));
+    assertEquals(1L, Math.floorDiv(Long.MIN_VALUE, Long.MIN_VALUE));
+    assertEquals(1L, Math.floorDiv(Long.MAX_VALUE, Long.MAX_VALUE));
+    assertEquals(Long.MIN_VALUE, Math.floorDiv(Long.MIN_VALUE, 1L));
+    assertEquals(Long.MAX_VALUE, Math.floorDiv(Long.MAX_VALUE, 1L));
+
+    // special case
+    assertEquals(Long.MIN_VALUE, Math.floorDiv(Long.MIN_VALUE, -1));
+
+    try {
+      Math.floorDiv(1L, 0L);
+      fail();
+    } catch (ArithmeticException expected) {
+    }
+  }
+
+  public void testFloorMod() {
+    assertEquals(0, Math.floorMod(0, 1));
+    assertEquals(1, Math.floorMod(4, 3));
+    assertEquals(-2, Math.floorMod(4, -3));
+    assertEquals(2, Math.floorMod(-4, 3));
+    assertEquals(-1, Math.floorMod(-4, -3));
+    assertEquals(0, Math.floorMod(Integer.MIN_VALUE, Integer.MIN_VALUE));
+    assertEquals(0, Math.floorMod(Integer.MAX_VALUE, Integer.MAX_VALUE));
+    assertEquals(0, Math.floorMod(Integer.MIN_VALUE, 1));
+    assertEquals(0, Math.floorMod(Integer.MAX_VALUE, 1));
+
+    try {
+      Math.floorMod(1, 0);
+      fail();
+    } catch (ArithmeticException expected) {
+    }
+  }
+
+  public void testFloorModLongs() {
+    assertEquals(0L, Math.floorMod(0L, 1L));
+    assertEquals(1L, Math.floorMod(4L, 3L));
+    assertEquals(-2L, Math.floorMod(4L, -3L));
+    assertEquals(2L, Math.floorMod(-4L, 3L));
+    assertEquals(-1L, Math.floorMod(-4L, -3L));
+    assertEquals(0L, Math.floorMod(Long.MIN_VALUE, Long.MIN_VALUE));
+    assertEquals(0L, Math.floorMod(Long.MAX_VALUE, Long.MAX_VALUE));
+    assertEquals(0L, Math.floorMod(Long.MIN_VALUE, 1L));
+    assertEquals(0L, Math.floorMod(Long.MAX_VALUE, 1L));
+
+    try {
+      Math.floorMod(1L, 0L);
+      fail();
+    } catch (ArithmeticException expected) {
+    }
+  }
+
+  public void testIncrementExact() {
+    for (int a : ALL_INTEGER_CANDIDATES) {
+      BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.ONE);
+      boolean expectedSuccess = fitsInInt(expectedResult);
+      try {
+        assertEquals(a + 1, Math.incrementExact(a));
+        assertTrue(expectedSuccess);
+      } catch (ArithmeticException e) {
+        assertFalse(expectedSuccess);
+      }
+    }
+  }
+
+  public void testIncrementExactLong() {
+    for (long a : ALL_LONG_CANDIDATES) {
+      BigInteger expectedResult = BigInteger.valueOf(a).add(BigInteger.ONE);
+      boolean expectedSuccess = fitsInLong(expectedResult);
+      try {
+        assertEquals(a + 1, Math.incrementExact(a));
+        assertTrue(expectedSuccess);
+      } catch (ArithmeticException e) {
+        assertFalse(expectedSuccess);
+      }
+    }
+  }
+
+  public void testMultiplyExact() {
+    for (int a : ALL_INTEGER_CANDIDATES) {
+      for (int b : ALL_INTEGER_CANDIDATES) {
+        BigInteger expectedResult = BigInteger.valueOf(a).multiply(BigInteger.valueOf(b));
+        boolean expectedSuccess = fitsInInt(expectedResult);
+        try {
+          assertEquals(a * b, Math.multiplyExact(a, b));
+          assertTrue(expectedSuccess);
+        } catch (ArithmeticException e) {
+          assertFalse(expectedSuccess);
+        }
+      }
+    }
+  }
+
+  public void testMultiplyExactLongs() {
+    for (long a : ALL_LONG_CANDIDATES) {
+      for (long b : ALL_LONG_CANDIDATES) {
+        BigInteger expectedResult = BigInteger.valueOf(a).multiply(BigInteger.valueOf(b));
+        boolean expectedSuccess = fitsInLong(expectedResult);
+        try {
+          assertEquals(a * b, Math.multiplyExact(a, b));
+          assertTrue(expectedSuccess);
+        } catch (ArithmeticException e) {
+          assertFalse(expectedSuccess);
+        }
+      }
+    }
+  }
+
+  public void testNegateExact() {
+    for (int a : ALL_INTEGER_CANDIDATES) {
+      BigInteger expectedResult = BigInteger.valueOf(a).negate();
+      boolean expectedSuccess = fitsInInt(expectedResult);
+      try {
+        assertEquals(-a, Math.negateExact(a));
+        assertTrue(expectedSuccess);
+      } catch (ArithmeticException e) {
+        assertFalse(expectedSuccess);
+      }
+    }
+  }
+
+  public void testNegateExactLong() {
+    for (long a : ALL_LONG_CANDIDATES) {
+      BigInteger expectedResult = BigInteger.valueOf(a).negate();
+      boolean expectedSuccess = fitsInLong(expectedResult);
+      try {
+        assertEquals(-a, Math.negateExact(a));
+        assertTrue(expectedSuccess);
+      } catch (ArithmeticException e) {
+        assertFalse(expectedSuccess);
+      }
+    }
+  }
+
+  public void testSubtractExact() {
+    for (int a : ALL_INTEGER_CANDIDATES) {
+      for (int b : ALL_INTEGER_CANDIDATES) {
+        BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.valueOf(b));
+        boolean expectedSuccess = fitsInInt(expectedResult);
+        try {
+          assertEquals(a - b, Math.subtractExact(a, b));
+          assertTrue(expectedSuccess);
+        } catch (ArithmeticException e) {
+          assertFalse(expectedSuccess);
+        }
+      }
+    }
+  }
+
+  public void testSubtractExactLongs() {
+    for (long a : ALL_LONG_CANDIDATES) {
+      for (long b : ALL_LONG_CANDIDATES) {
+        BigInteger expectedResult = BigInteger.valueOf(a).subtract(BigInteger.valueOf(b));
+        boolean expectedSuccess = fitsInLong(expectedResult);
+        try {
+          assertEquals(a - b, Math.subtractExact(a, b));
+          assertTrue(expectedSuccess);
+        } catch (ArithmeticException e) {
+          assertFalse(expectedSuccess);
+        }
+      }
+    }
+  }
+
+  public void testToIntExact() {
+    final long[] longs = {0, -1, 1, Integer.MIN_VALUE, Integer.MAX_VALUE,
+        Integer.MIN_VALUE - 1L, Integer.MAX_VALUE + 1L, Long.MIN_VALUE, Long.MAX_VALUE};
+    for (long a : longs) {
+      boolean expectedSuccess = (int) a == a;
+      try {
+        assertEquals((int) a, Math.toIntExact(a));
+        assertTrue(expectedSuccess);
+      } catch (ArithmeticException e) {
+        assertFalse(expectedSuccess);
+      }
+    }
+  }
+
+  private static boolean fitsInInt(BigInteger big) {
+    return big.bitLength() < Integer.SIZE;
+  }
+
+  private static boolean fitsInLong(BigInteger big) {
+    return big.bitLength() < Long.SIZE;
+  }
+
+  private static Integer[] getAllIntegerCandidates() {
+    ArrayList<Integer> candidates = new ArrayList<Integer>();
+    candidates.add(0);
+    candidates.add(-1);
+    candidates.add(1);
+    candidates.add(Integer.MAX_VALUE / 2);
+    candidates.add(Integer.MAX_VALUE / 2 - 1);
+    candidates.add(Integer.MAX_VALUE / 2 + 1);
+    candidates.add(Integer.MIN_VALUE / 2);
+    candidates.add(Integer.MIN_VALUE / 2 - 1);
+    candidates.add(Integer.MIN_VALUE / 2 + 1);
+    candidates.add(Integer.MAX_VALUE - 1);
+    candidates.add(Integer.MAX_VALUE);
+    candidates.add(Integer.MIN_VALUE + 1);
+    candidates.add(Integer.MIN_VALUE);
+    return candidates.toArray(new Integer[candidates.size()]);
+  }
+
+  private static Long[] getAllLongCandidates() {
+    ArrayList<Long> candidates = new ArrayList<Long>();
+
+    for (Integer x : getAllIntegerCandidates()) {
+      candidates.add(x.longValue());
+    }
+
+    candidates.add(Long.MAX_VALUE / 2);
+    candidates.add(Long.MAX_VALUE / 2 - 1);
+    candidates.add(Long.MAX_VALUE / 2 + 1);
+    candidates.add(Long.MIN_VALUE / 2);
+    candidates.add(Long.MIN_VALUE / 2 - 1);
+    candidates.add(Long.MIN_VALUE / 2 + 1);
+    candidates.add(Integer.MAX_VALUE + 1L);
+    candidates.add(Long.MAX_VALUE - 1L);
+    candidates.add(Long.MAX_VALUE);
+    candidates.add(Integer.MIN_VALUE - 1L);
+    candidates.add(Long.MIN_VALUE + 1L);
+    candidates.add(Long.MIN_VALUE);
+
+    return candidates.toArray(new Long[candidates.size()]);
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java8/lang/StringTest.java b/user/test/com/google/gwt/emultest/java8/lang/StringTest.java
new file mode 100644
index 0000000..67dace4
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/lang/StringTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * 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.
+ */
+package com.google.gwt.emultest.java8.lang;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.Arrays;
+
+/**
+ * Java8 String tests.
+ */
+public class StringTest extends GWTTestCase {
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.emultest.EmulSuite";
+  }
+
+  public void testJoin() {
+    assertEquals("", String.join("", ""));
+    assertEquals("", String.join(",", ""));
+    assertEquals("", String.join(",", Arrays.<String>asList()));
+
+    assertEquals("a", String.join("", "a"));
+    assertEquals("a", String.join(",", "a"));
+    assertEquals("a", String.join(",", Arrays.asList("a")));
+
+    assertEquals("ab", String.join("", "a", "b"));
+    assertEquals("a,b", String.join(",", "a", "b"));
+    assertEquals("a,b", String.join(",", Arrays.asList("a", "b")));
+
+    assertEquals("abc", String.join("", "a", "b", "c"));
+    assertEquals("a,b,c", String.join(",", "a", "b", "c"));
+    assertEquals("a,b,c", String.join(",", Arrays.asList("a", "b", "c")));
+  }
+
+}