changeset 9693:400550ebd6e9

Refactor stream test by decoupling data and operation
author hyan
date Thu, 29 Aug 2013 00:12:11 +0800
parents b1e1b93ea1b5
children 8f758169da25
files test/java/util/stream/Stream/BaseStreamTest.java test/java/util/stream/Stream/CollectTest.java test/java/util/stream/Stream/CollectorsTest.java test/java/util/stream/Stream/ConcatTest.java test/java/util/stream/Stream/CountTest.java test/java/util/stream/Stream/DistinctTest.java test/java/util/stream/Stream/EmployeeStreamTest.java test/java/util/stream/Stream/FilterTest.java test/java/util/stream/Stream/FindTest.java test/java/util/stream/Stream/FlatMapTest.java test/java/util/stream/Stream/ForEachTest.java test/java/util/stream/Stream/GenericStreamTest.java test/java/util/stream/Stream/IntegerReduceTest.java test/java/util/stream/Stream/IntegerStreamTest.java test/java/util/stream/Stream/LimitTest.java test/java/util/stream/Stream/MatchTest.java test/java/util/stream/Stream/MaxAndMinTest.java test/java/util/stream/Stream/OperatorTest.java test/java/util/stream/Stream/PeekTest.java test/java/util/stream/Stream/ReduceTest.java test/java/util/stream/Stream/SortedTest.java test/java/util/stream/Stream/SortedTestForCompable.java test/java/util/stream/Stream/SortedTestForNonCompable.java test/java/util/stream/Stream/StringBuilderSpecialTest.java test/java/util/stream/Stream/StringBuilderStreamTest.java test/java/util/stream/Stream/SubstreamTest.java test/java/util/stream/Stream/ToArrayTest.java
diffstat 27 files changed, 2694 insertions(+), 1120 deletions(-) [+]
line wrap: on
line diff
--- a/test/java/util/stream/Stream/BaseStreamTest.java	Tue Aug 27 12:38:34 2013 +0200
+++ b/test/java/util/stream/Stream/BaseStreamTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -20,7 +20,57 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+import java.util.Random;
 
-public class BaseStreamTest {
+public abstract class BaseStreamTest {
+    public ParallelType getParallelType() {
+        return parallelType;
+    }
+    protected enum ParallelType { Parallel, Sequential, Default }
+
+    //Test data size
+    protected final static int VERY_SMALL_DATA_SIZE = 1;
     
+    protected final static int SMALL_DATA_SIZE = 1 << 2;
+
+    //MIN_PARTITION
+    protected final static int PARTITION_DATA_SIZE = 1 << 4;
+    
+    protected final static int MEDIUM_DATA_SIZE = 1 << 7;
+   
+    protected final static int[] ALL_DATA_SIZES = {    
+  
+                MEDIUM_DATA_SIZE,
+                PARTITION_DATA_SIZE,
+                SMALL_DATA_SIZE,
+                VERY_SMALL_DATA_SIZE
+    };
+
+    protected final static int[] MEDIUM_DATA_SIZES = {    
+                MEDIUM_DATA_SIZE,
+                PARTITION_DATA_SIZE,
+                SMALL_DATA_SIZE,
+                VERY_SMALL_DATA_SIZE
+    };
+        
+      protected final static  int[] SMALL_DATA_SIZES = {    
+                SMALL_DATA_SIZE,
+                PARTITION_DATA_SIZE,
+                VERY_SMALL_DATA_SIZE
+    };
+    
+    protected final static int SIXTY_FOUR = 64;
+
+    protected final static Random rand = new Random(433494437);
+    
+    protected final ParallelType parallelType;
+    
+    BaseStreamTest(ParallelType parallelType) {
+        this.parallelType = parallelType;
+    }
+
+    @FunctionalInterface
+    public interface TripleFunction<L, M, N, I> { 
+        public I apply(L l, M m, N n);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/CollectTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class CollectTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public CollectTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    public void testCollectByGroupingBy(String desc, Collection<U> col, Function<U, ? extends Object> mapFunc) {
+        Map<Object, List<U>> result = streamFor(col). collect(Collectors.<U, Object>groupingBy(mapFunc));
+        result.keySet().stream().forEach((key) -> {
+            result.get(key).stream().forEach((u) -> {
+                assertEquals(key, mapFunc.apply(u));
+            });
+        });
+        assertEqualContents(result.values().stream().flatMap(l -> l.stream()).collect(Collectors.<U>toList()), col, 
+                test.getNaturalOrderComparator());
+        assertTrue(streamFor(createEmptyCollection()).
+                collect(Collectors.<U, Object>groupingBy(mapFunc)).isEmpty());
+    }
+
+    public void testCollectByPartition(String desc, Collection<U> col, Predicate<U> mapFunc) {
+        Map<Boolean, List<U>> partition = streamFor(col). collect(Collectors.<U>partitioningBy(mapFunc));
+        Map<Boolean, List<U>> emptyPartition 
+                = streamFor(createEmptyCollection()).collect(Collectors.<U>partitioningBy(mapFunc));
+        Arrays.asList(true, false).forEach(key -> {
+            partition.get(key).stream().forEach((u) -> {
+                assertEquals(mapFunc.test(u), key.booleanValue());
+            });
+           assertTrue(emptyPartition.get(false).isEmpty()); 
+        });
+    }
+
+    @Test(dataProvider="collectionKeyValueFunctionData", threadPoolSize = 3)
+    public <K, V> void testCollectToMap(String desc, Collection<U> col, Function<U, K> keyFunc, 
+            Function<U, V> valueFunc) {
+        Map<K, V> keyToValue = streamFor(col).collect(Collectors.<U, K, V>toMap(keyFunc, valueFunc));
+        assertEquals(keyToValue.size(), streamFor(col).map(keyFunc).distinct().count());
+        col.stream().forEach((u) -> {
+            assertEquals(valueFunc.apply(u), keyToValue.get(keyFunc.apply(u)));
+        });
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/CollectorsTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary function test for Collectors' static methods
+ * @(#) CollectorsTest.java
+ * @run testng CollectorsTest
+ * @author Tristan Yan
+ */
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class CollectorsTest {
+     private final static long COLLECTION_SIZE = 1 << 8;
+     
+     private final static Random RAND = new Random(System.nanoTime());
+
+     @Test(dataProvider="streams")
+     public void testCounting(Collection<Integer> c) {
+         assertEquals(c.stream().collect(Collectors.counting()).longValue(),
+                 COLLECTION_SIZE);
+     }
+ 
+     @Test(dataProvider="streams")
+     public void testGroupingBy(Collection<Integer> c) {
+         Map<Integer, List<Integer>> map = c.parallelStream().
+                 collect(Collectors.groupingBy(Integer::lowestOneBit));
+         map.forEach((i, l) -> {
+             for(Integer li : l) {
+                 assertEquals(Integer.lowestOneBit(li), i.intValue());
+             }
+         });
+
+         Map<Integer, List<Integer>> mapConcurrent = c.parallelStream().collect(
+                 Collectors.groupingByConcurrent(Integer::highestOneBit));
+         mapConcurrent.forEach((i, l) -> {
+             for(Integer li : l) {
+                 assertEquals(Integer.highestOneBit(li), i.intValue());
+             }
+         });
+     }
+
+     @Test(dataProvider="streams")
+     public void testGroupingByWithCollector(Collection<Integer> c) {
+         Map<Integer, Set<Integer>> map = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::lowestOneBit, 
+            Collectors.mapping(Integer::lowestOneBit,
+                 Collectors.<Integer>toSet())));
+         map.forEach((i, s) -> {
+            assertEquals(s.size(), 1);
+            assertEquals(s.toArray()[0], i);
+         });
+
+        Map<Integer, Set<Integer>> mapConcurrent = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::highestOneBit, 
+            Collectors.mapping(Integer::highestOneBit,
+                Collectors.<Integer>toSet())));
+         mapConcurrent.forEach((i, s) -> {
+            assertEquals(s.size(), 1);
+            assertEquals(s.toArray()[0], i);
+         });
+     }
+
+     @Test(dataProvider="streams")
+     public void testGroupingByWithCollectorFactory(Collection<Integer> c) {
+         Map<Integer, Set<Integer>> map = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::lowestOneBit, TreeMap::new,
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         final AtomicInteger lowerBit = new AtomicInteger(-1);
+         map.forEach((i, s) -> {
+            assertTrue(i > lowerBit.getAndSet(i));
+            final AtomicInteger smallest = new AtomicInteger(Integer.MIN_VALUE);
+            s.forEach(v -> {
+                assertTrue(v >= smallest.getAndSet(v));
+            });
+         });
+
+         Map<Integer, Set<Integer>> mapConcurrent = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::lowestOneBit, TreeMap::new,
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         final AtomicInteger higherBit = new AtomicInteger(-1);
+         mapConcurrent.forEach((i, s) -> {
+            assertTrue(i > higherBit.getAndSet(i));
+            final AtomicInteger smallest = new AtomicInteger(Integer.MIN_VALUE);
+            s.forEach(v -> {
+                assertTrue(v >= smallest.getAndSet(v));
+            });
+         });
+     }
+     
+     @Test(dataProvider="streams")
+     public void testMapping(Collection<Integer> c) {
+         Function<Integer, String> itos = String::valueOf;
+         Function<Integer,Integer> lenFunc = itos.andThen(Integer::parseInt);
+         List<Integer> l = c.stream().collect(Collectors.mapping(lenFunc,
+                 Collectors.toList()));
+         assertEquals(l.size(), c.size());
+         Iterator<Integer> iter1 = c.iterator();
+         Iterator<Integer> iter2 = l.iterator();
+         while(iter1.hasNext() && iter2.hasNext()) {
+             assertEquals(iter1.next(), iter2.next());
+         } 
+     }
+
+     @Test(dataProvider="streams")
+     public void testMaxBy(Collection<Integer> c) {
+         Function<Integer, Integer> f = Math::abs;
+         Comparator<Integer> c1 = Comparator.comparing(f);
+         Integer max = c.stream().collect(Collectors.maxBy(c1)).get();
+         int maxExpected
+                 = c.stream().mapToInt(i -> Math.abs(i)).max().getAsInt();
+         assertEquals(Math.abs(max.intValue()), maxExpected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testMinBy(Collection<Integer> c) {
+         Comparator<Integer> c1  = Comparator.<Integer,Integer>comparing(i -> i * -1);
+         Integer max = c.stream().collect(Collectors.minBy(c1)).get();
+         int maxExpected  = c.stream().mapToInt(i -> i.intValue()).max().getAsInt();
+         assertEquals(max.intValue(), maxExpected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testPartitionBy(Collection<Integer> c) {
+         Map<Boolean, List<Integer>> partition = c.stream().
+                 collect(Collectors.partitioningBy(i -> i > 0));
+         List<Integer> greaterThanZero = partition.get(true);
+         List<Integer> notGreaterThanZero = partition.get(false);
+         for(int i :  greaterThanZero)
+             assertTrue(i > 0);
+         for(int i :  notGreaterThanZero)
+             assertFalse(i > 0);
+     }
+
+     @Test(dataProvider="streams")
+     public void testPartitionByWithCollector(Collection<Integer> c) {
+         Map<Boolean, Set<Integer>> partition = c.stream().
+                 collect(Collectors.partitioningBy(i -> (i & 0x01) == 0x01, 
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         Set<Integer> odds = partition.get(true);
+         Set<Integer> evens = partition.get(false);
+         int smallest = Integer.MIN_VALUE;
+         for(int i :  odds) {
+             assertTrue((i & 0x01) == 0x01);
+             assertTrue( i >= smallest);
+             smallest = i;
+         }
+         
+         smallest = Integer.MIN_VALUE;
+         for(int i :  evens){
+             assertTrue((i & 0x01) == 0x0);
+             assertTrue( i >= smallest);
+             smallest = i;
+         }
+     }
+
+     @Test(dataProvider="streams")
+     public void testReducing(Collection<Integer> c) {
+         Function<Integer, Integer> absFunc = Math::abs;
+         Comparator<Integer> comp = Comparator.comparing(absFunc);
+         BinaryOperator<Integer> shortest = BinaryOperator.minBy(comp);
+         Integer smallestPositive = c.stream().collect(Collectors.reducing(shortest)).get();
+         int expected = c.stream().mapToInt(Math::abs).min().getAsInt();
+         assertEquals(Math.abs(smallestPositive.intValue()), expected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testReducingWithIdentity(Collection<Integer> c) {
+         Map<Integer, Integer> map = c.stream().collect(Collectors.groupingBy(
+             Integer::lowestOneBit, Collectors.reducing(0, (i1, i2) -> i1++)));
+         Map<Integer, List<Integer>> mapCal = c.stream().
+                 map(Integer::lowestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         mapCal.forEach((i, l) -> {
+             assertEquals(l.size(), map.get(i).intValue());
+         });
+     }
+
+     @Test(dataProvider="streams")
+     public void testReducingWithMapper(Collection<Integer> c) {
+         Function<Integer, String> itos = String::valueOf;
+         Function<String, Integer> lenF = String::length;
+         int totalLen = c.stream().collect(Collectors.<Integer, Integer>reducing(
+                 0, itos.andThen(lenF), Integer::sum));
+         int expected
+                 = c.stream().mapToInt(i -> String.valueOf(i).length()).sum();
+         assertEquals(totalLen, expected);
+     } 
+
+     @Test(dataProvider="streams")
+     public void testSumBy(Collection<Integer> c) {
+         Long posOverNeg = c.stream().collect(Collectors.summarizingLong( i -> new Long(Integer.signum(i)))).getSum();
+         int expected = c.stream().mapToInt(Integer::signum).sum();
+         assertEquals(posOverNeg.intValue(), expected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testToCollection(Collection<Integer> c) {
+         ArrayDeque<Integer> ad = c.stream().sequential().
+                 collect(Collectors.toCollection(ArrayDeque<Integer>::new));
+         assertEquals(ad, new ArrayDeque<>(c));
+         ArrayList<Integer> al = c.stream().sequential().
+                 collect(Collectors.toCollection(ArrayList<Integer>::new));
+         assertEquals(al, new ArrayList<>(c));
+         ConcurrentLinkedDeque<Integer> cld = c.stream().sequential().collect(
+                 Collectors.toCollection(ConcurrentLinkedDeque<Integer>::new));
+         assertEquals(cld, new ConcurrentLinkedDeque<>(c));
+         ConcurrentLinkedQueue<Integer> clq = c.stream().sequential().collect(
+                 Collectors.toCollection(ConcurrentLinkedQueue<Integer>::new));
+         assertEquals(clq, new ConcurrentLinkedQueue<>(c));
+         ConcurrentSkipListSet<Integer> ckls = c.stream().sequential().collect(
+                 Collectors.toCollection(ConcurrentSkipListSet<Integer>::new));
+         assertEquals(ckls, new ConcurrentSkipListSet<>(c));
+         CopyOnWriteArrayList<Integer> cowal = c.stream().sequential().collect(
+                 Collectors.toCollection(CopyOnWriteArrayList<Integer>::new));
+         assertEquals(cowal, new CopyOnWriteArrayList<>(c));
+         HashSet<Integer> hs = c.stream().
+                 collect(Collectors.toCollection(HashSet<Integer>::new));
+         assertEquals(hs, new HashSet<>(c));
+         LinkedBlockingDeque<Integer> lbd = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedBlockingDeque<Integer>::new));
+         assertEquals(lbd, new LinkedBlockingDeque<>(c));
+         LinkedBlockingQueue<Integer> lbq = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedBlockingQueue<Integer>::new));
+         assertEquals(lbq, new LinkedBlockingQueue<>(c));
+         LinkedHashSet<Integer> lhs = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedHashSet<Integer>::new));
+         assertEquals(lhs, new LinkedHashSet<>(c));
+         LinkedList<Integer> ll = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedList<Integer>::new));
+         assertEquals(ll, new LinkedList<>(c));
+         LinkedTransferQueue<Integer> ltq = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedTransferQueue<Integer>::new));
+         assertEquals(ltq, new LinkedTransferQueue<>(c));
+
+         //PriorityQueue doesn't guarante to traverse the elements of in any 
+         //particular order, we're using Arrays.sort(pq.toArray()) verify 
+         //result
+         PriorityBlockingQueue<Integer> pbq = c.stream().sequential().collect(
+                 Collectors.toCollection(PriorityBlockingQueue<Integer>::new));
+         PriorityBlockingQueue<Integer> pbqExpected
+                 = new PriorityBlockingQueue<>(c);
+         Object[] pbqArr = pbq.toArray();
+         Object[] pbqExpectedArr = pbqExpected.toArray();
+         Arrays.sort(pbqArr);
+         Arrays.sort(pbqExpectedArr);
+         assertEquals(pbqArr, pbqExpectedArr);
+
+         PriorityQueue<Integer> pq = c.stream().sequential().collect(
+                 Collectors.toCollection(PriorityQueue<Integer>::new));
+         PriorityQueue<Integer> pqExpected = new PriorityQueue<>(c);
+         Object[] pqArr = pq.toArray();
+         Object[] pqExpectedArr = pqExpected.toArray();
+         Arrays.sort(pqArr);
+         Arrays.sort(pqExpectedArr);
+         assertEquals(pqArr, pqExpectedArr);
+
+         Stack<Integer> s = c.stream().sequential().collect(Collectors.
+                 toCollection(Stack<Integer>::new));
+         Stack<Integer> sExpected = new Stack<>();
+         sExpected.addAll(c);
+         assertEquals(s, sExpected);
+         TreeSet<Integer> ts = c.stream().sequential().collect(Collectors.
+                 toCollection(TreeSet<Integer>::new));
+         assertEquals(ts, new TreeSet<>(c));
+         Vector<Integer> v = c.stream().sequential().collect(Collectors.
+                 toCollection(Vector<Integer>::new));
+         assertEquals(v, new Vector<>(c));
+     }
+     
+     @Test(dataProvider="streams")
+     public void testToMap(Collection<Integer> c) {
+         Map<Integer, String> map = c.stream().collect(
+                 Collectors.toMap(Function.identity(), String::valueOf));
+         map.forEach((k, v) -> {
+             assertEquals(k.intValue(), Integer.parseInt(v));
+         });
+         Map<Integer, String> concurrentMap = c.stream().collect(
+                 Collectors.toConcurrentMap(Function.identity(), String::valueOf));
+         concurrentMap.forEach((k, v) -> {
+             assertEquals(k.intValue(), Integer.parseInt(v));
+         });
+     }
+     
+     @Test(dataProvider="streams")
+     public void testToMapWithOperator(Collection<Integer> c) {
+         Map<Integer, Integer> map = c.stream().collect(
+                Collectors.toMap(Integer::highestOneBit, i -> 1, Integer::sum));
+         Map<Integer, List<Integer>> hmap = c.stream().
+                 map(Integer::highestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(map.size(), hmap.size());
+         map.forEach((k , v) -> {
+             assertEquals(v.intValue(), hmap.get(k).size());
+         });
+
+         Map<Integer, Integer> concurrentMap = c.stream().collect(
+                 Collectors.toConcurrentMap(Integer::lowestOneBit, i -> 1,
+                 Integer::sum));
+         Map<Integer, List<Integer>> lmap = c.stream().
+                 map(Integer::lowestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(concurrentMap.size(), lmap.size());
+         concurrentMap.forEach((k , v) -> {
+             assertEquals(v.intValue(), lmap.get(k).size());
+         });
+     }
+     
+     @Test(dataProvider="streams")
+     public void testToMapWithOperatorAndSupplier(Collection<Integer> c) {
+         Map<Integer, Integer> map = c.stream().collect(
+                 Collectors.toMap(Integer::highestOneBit, i -> 1, Integer::sum,
+                 TreeMap::new));
+         Map<Integer, List<Integer>> hmap = c.stream().
+                 map(Integer::highestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(map.size(), hmap.size());
+         
+         AtomicInteger lowerKey = new AtomicInteger(Integer.MIN_VALUE);
+         map.forEach((k , v) -> {
+             assertTrue(k >= lowerKey.getAndSet(k));
+             assertEquals(v.intValue(), hmap.get(k).size());
+         });
+
+         Map<Integer, Integer> concurrentMap = c.stream().collect(
+                 Collectors.toConcurrentMap(Integer::lowestOneBit, i -> 1,
+                 Integer::sum, ConcurrentSkipListMap::new));
+         Map<Integer, List<Integer>> lmap = c.stream().
+                 map(Integer::lowestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(concurrentMap.size(), lmap.size());
+         lowerKey.set(Integer.MIN_VALUE);
+         concurrentMap.forEach((k , v) -> {
+             assertTrue(k >= lowerKey.getAndSet(k));
+             assertEquals(v.intValue(), lmap.get(k).size());
+         });
+     }
+        
+     @Test(dataProvider="streams")
+     public void testToDoubleSummaryStatistics(Collection<Integer> c){
+         DoubleSummaryStatistics dss = c.stream().collect(Collectors.summarizingDouble(Integer::doubleValue));
+         IntSummaryStatistics iss = c.stream().mapToInt(Integer::intValue).summaryStatistics();
+         assertEquals(dss.getAverage(), iss.getAverage());
+         assertEquals(dss.getCount(), c.size());
+         assertEquals(dss.getSum(), (double)iss.getSum());
+     }
+        
+     @Test(dataProvider="streams")
+     public void testToIntSummaryStatistics(Collection<Integer> c){
+         IntSummaryStatistics iss = c.stream().collect(Collectors.summarizingInt(Math::abs));
+         assertEquals(iss.getAverage(), 
+                 c.stream().mapToInt(Math::abs).average().getAsDouble());
+         assertEquals(iss.getCount(), c.size());
+         assertEquals(iss.getSum(),  c.stream().mapToLong(i -> Math.abs(i)).sum());
+     }
+        
+     @Test(dataProvider="streams")
+     public void testToLongSummaryStatistics(Collection<Integer> c){
+         LongSummaryStatistics lss = c.stream().collect(Collectors.summarizingLong(i -> (long)Math.pow(i, 2)));
+         assertEquals(lss.getAverage(), c.stream().mapToLong(i -> (long)Math.pow(i, 2)).average().getAsDouble());
+         assertEquals(lss.getCount(), c.size());
+         assertEquals(lss.getSum(), c.stream().mapToLong(i -> (long)Math.pow(i, 2)).sum());
+     }
+
+     @Test
+     public void testEmpty(){
+         Stream<Integer> stream = Stream.<Integer>empty();
+         assertEquals(0, Stream.<Integer>empty().collect(Collectors.counting()).intValue());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.
+                 <Integer, Integer>groupingBy(Function.identity())).isEmpty());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.groupingBy(
+                 Function.identity(), Collectors.<Integer>toSet())).isEmpty());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.groupingBy(Function.identity(), TreeMap::new,
+                 Collectors.toCollection(TreeSet<Integer>::new))).isEmpty());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.mapping(
+                 Function.identity(), Collectors.toList())).isEmpty());
+         assertFalse(Stream.<Integer>empty().collect(Collectors.maxBy(Comparator.naturalOrder())).isPresent());
+         Map<Boolean, List<Integer>> partition1 = Stream.<Integer>empty().
+                 collect(Collectors.partitioningBy(i -> i > 0));
+         assertTrue(partition1.get(true).isEmpty());
+         assertTrue(partition1.get(false).isEmpty());
+         
+         Map<Boolean, Set<Integer>> partition2 = Stream.<Integer>empty().
+                 collect(Collectors.partitioningBy(i -> (i & 0x01) == 0x01, 
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         assertTrue(partition2.get(true).isEmpty());
+         assertTrue(partition2.get(false).isEmpty());
+         
+         Comparator<Integer> comp = Comparator.comparing(Function.identity());
+         BinaryOperator<Integer> largest = BinaryOperator.maxBy(comp);
+         assertFalse(Stream.<Integer>empty().collect(Collectors.reducing(largest)).isPresent());
+     }
+
+     
+     @DataProvider
+     public static Object[][] streams() {
+         Supplier<Collection<Integer>>[] suppliers = new Supplier[]{
+             ArrayDeque<Integer>::new,
+             ArrayList<Integer>::new,
+             ConcurrentLinkedDeque<Integer>::new,
+             ConcurrentLinkedQueue<Integer>::new,
+             ConcurrentSkipListSet<Integer>::new,
+             CopyOnWriteArrayList<Integer>::new,
+             HashSet<Integer>::new,
+             LinkedBlockingDeque<Integer>::new,
+             LinkedBlockingQueue<Integer>::new,
+             LinkedHashSet<Integer>::new,
+             LinkedList<Integer>::new,
+             LinkedTransferQueue<Integer>::new,
+             PriorityBlockingQueue<Integer>::new,
+             PriorityQueue<Integer>::new,
+             Stack<Integer>::new,
+             TreeSet<Integer>::new,
+             Vector<Integer>::new,
+         };
+         Object[][] params = new Object[suppliers.length][1];
+         int index = 0;
+         for(Supplier<Collection<Integer>> s: suppliers) {
+             Collection<Integer> c = s.get();
+             for(int i = 0; i < COLLECTION_SIZE; i++) {
+                 c.add(RAND.nextInt());
+             }
+             params[index++][0] = c;
+         }
+         return params;
+     }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ConcatTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.testng.annotations.Test;
+
+public class ConcatTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ConcatTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="concatCollectionData")
+    public void testConcat(String desc, Collection<U> tobeConcated, Collection<U> concat) {
+        //We're using List to store expected result because Set could merge object, 
+        Collection<U> expected = new ArrayList<>(tobeConcated);
+        expected.addAll(concat);
+
+        //test concat with parallel/non-parallel Stream
+        for(BaseStreamTest.ParallelType concatType : BaseStreamTest.ParallelType.values()) {
+            Stream<U> concatStream = (concatType == BaseStreamTest.ParallelType.Parallel) ? 
+                concat.parallelStream(): (concatType == BaseStreamTest.ParallelType.Sequential)
+                ? concat.parallelStream().sequential() : concat.stream();
+            List<U> calculated = Stream.concat(streamFor(tobeConcated), concatStream)
+                    .collect(Collectors.<U>toList());
+            assertEqualContents(calculated, expected, test.getNaturalOrderComparator());
+        }
+
+        List<U> result3 = Stream.concat(tobeConcated.stream(), streamFor(createEmptyCollection()))
+                .collect(Collectors.<U>toList());
+        List<U> result4 = Stream.concat(tobeConcated.stream(), Stream.empty())
+                .collect(Collectors.<U>toList());
+        assertEqualContents(tobeConcated, result3, test.getNaturalOrderComparator());
+        assertEqualContents(tobeConcated, result4, test.getNaturalOrderComparator());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/CountTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class CountTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public CountTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionData")
+    public void testCount(String desc, Collection<U> col) {
+        assertEquals(streamFor(col).count(), col.size());
+        assertEquals(streamFor(col).count(), streamFor(col).mapToLong(u -> 1).sum());
+        assertEquals(streamFor(createEmptyCollection()).count(), 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/DistinctTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class DistinctTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public DistinctTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionDataWithSelection")
+    public void testDistinct(String desc, Collection<U> col, Function<U, Stream<U>> mapper)  {
+        Set<U> set = new HashSet<>(col);
+
+        List<U> expected = streamFor(col).flatMap(mapper).distinct().collect(Collectors.<U>toList());
+        if(expected.size() != 0) {
+            assertEqualContents(expected, set, test.getNaturalOrderComparator());
+        } else {
+            assertEquals(mapper.apply(streamFor(col).findAny().get()).count(), 0);
+        }       
+        assertEquals(streamFor(createEmptyCollection()).distinct().count(), 0);
+    }
+}
\ No newline at end of file
--- a/test/java/util/stream/Stream/EmployeeStreamTest.java	Tue Aug 27 12:38:34 2013 +0200
+++ b/test/java/util/stream/Stream/EmployeeStreamTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -1,307 +1,319 @@
-/*
- * Copyright (c) 2013, 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.
- *
- * 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.
- */
-
-/**
- * @test
- * @summary Basic test for Stream<Employee>
- * @library /sqeutil
- * @(#) EmployeeStreamTest.java
- * @author Eric Wang/Tristan Yan
- * @run testng/othervm -mx1g EmployeeStreamTest
- */
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Objects;
-import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
-import java.util.function.Function;
-import java.util.function.IntFunction;
-import java.util.function.ToIntFunction;
-import org.testng.annotations.Factory;
-
-class Employee implements Comparable<Employee>, Cloneable {
-    static final int ID_LENGTH = 6;
-    static final int MIN_BIRTHDAY = 1900;
-    static final int MAX_BIRTHDAY = 2050;
-    static final int MIN_PAY = 1000;
-    static final int MAX_PAY = 100000;
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    } 
-        
-    public int getBirthday() {
-        return birthday;
-    }
-
-    public boolean isMale() {
-        return male;
-    }
-
-    public double getPay() {
-        return pay;
-    }
-
-    public void setPay(double pay) {
-        this.pay = pay;
-    }  
-
-    public Title getTitle() {
-        return title;
-    }
-
-    public void setTitle(Title title) {
-        this.title = title;
-    }
-    public Employee(String id, int birthday, boolean male, double pay, Title title) {
-        this.id = id;
-        this.birthday = birthday;
-        this.male = male;
-        this.pay = pay;
-        this.title = title;
-    }
-
-    static enum Title {
-        SE, SSE, PSE, CSE, ARCHITECT, M1, M2, M3, M4
-    }
-
-    static enum Rule {
-        ID {
-            @Override
-            Function<Employee, String> empFunc() {
-                return Employee::getId;
-            }
-            @Override
-            String funcName(){
-                return "Employee::getId";
-            }
-        },
-        BIRTHDAY {
-            @Override
-            Function<Employee, Integer> empFunc() {
-                return Employee::getBirthday;
-            }
-            @Override
-            String funcName(){
-                return "Employee::getBirthday";
-            }
-        },
-        MALE {
-            @Override
-            Function<Employee, Boolean> empFunc() {
-                return Employee::isMale;
-            }
-            @Override
-            String funcName(){
-                return "Employee::isMale";
-            }
-        },
-        PAY {
-            @Override
-            Function<Employee, Double> empFunc() {
-                return Employee::getPay;
-            }
-            @Override
-            String funcName(){
-                return "Employee::getPay";
-            }
-        },
-        TITLE {
-            @Override
-            Function<Employee, Title> empFunc(){
-                return Employee::getTitle;
-            }
-
-            @Override
-            String funcName(){
-                return "Employee::getTitle";
-            }
-        };
-
-        Comparator<Employee> getComparator() {
-            return Comparator.comparing(empFunc());
-        }
-
-        Object getValue(Employee e) { return empFunc().apply(e); }
-        
-        abstract String funcName();
-        
-        abstract Function<Employee, ? extends Comparable> empFunc();
-    }
- 
-    private String id;
-    private final int birthday;
-    private final boolean male;
-    private double pay;
-    private Title title;
-
-    @Override
-    public boolean equals(Object other) {
-        if (other instanceof Employee) {
-            Employee compared = (Employee) other;
-            return id.equals(compared.getId()) && birthday == compared.getBirthday()
-                    && male == compared.isMale() && pay == compared.getPay()
-                    && title == compared.getTitle();
-        } 
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(this.id);
-    }
-
-    @Override
-    public int compareTo(Employee t) {
-        return id.compareTo(t.getId());
-    }
-
-    @Override
-    public Employee clone() {
-        try {
-            return (Employee)super.clone();
-        } catch (CloneNotSupportedException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "id=" + getId() + ", birthday=" + getBirthday() + ". male=" + isMale()
-                + ", pay=" + getPay() + ", title=" + getTitle();
-    }
-}
-
-public class EmployeeStreamTest<T extends Collection<Employee>> extends
-            GenericStreamTest<Employee, Collection<Employee>> {
-    public EmployeeStreamTest(Class clazz, 
-            ParallelType parallelType, int initSize) {
-        super(clazz, parallelType, Comparator.naturalOrder(), initSize);
-    }
-
-    public EmployeeStreamTest(Class clazz, 
-            ParallelType parallelType) {
-        super(clazz, parallelType, Comparator.naturalOrder());
-    }
-
-    @Factory
-    public static Object[] create(){
-      TripleFunction<Class,ParallelType,Integer, EmployeeStreamTest> supplierWithInitSize =
-              EmployeeStreamTest<Collection<Employee>>::<Class,ParallelType,Integer>new;
-      BiFunction<Class,ParallelType,EmployeeStreamTest> supplier =
-              EmployeeStreamTest<Collection<Employee>>::<Class,ParallelType>new;
-      return GenericStreamTest.create(supplierWithInitSize, supplier, true);
-    }
-
-    @Override
-    public String getTestName() {
-        return typeObject.getName() + "<Employee>";
-    }
-
-    @Override
-    protected Object[] predicateAndDesc(int size) {
-        Employee limit = createEmployee();
-        boolean isUp = rand.nextBoolean();
-        Employee.Rule rule = Arrays.stream(Employee.Rule.values()).findAny().get();
-        return new Object[]{ LambdaUtilities.randomGenericPredicate(isUp, limit, rule.getComparator()), 
-                String.format("emp -> Comparator.comparing(%s).compare(emp, %s) %s 0", rule.funcName(), isUp ? ">=" : "<", limit)};
-    }
-    
-    //Function<U, ? extends Comparable>, descrption for Function<? extends Comparable>
-    @Override
-    protected Object[][] functionAndDesc(){
-            return Arrays.stream(Employee.Rule.values()).map(rule -> new Object[]{rule.empFunc(), rule.funcName()})
-                    .toArray(Object[][]::new);   
-    }
-   
-    //BinaryOperator, descrption, stateless
-    @Override
-    protected Object[][] binaryOperatorAndDesc() {
-        BinaryOperator<Employee> maxOp = (e1, e2) -> naturalOrderComparator.compare(e1, e2) < 0 ? e2 : e1;
-        BinaryOperator<Employee> minOp =  (e1, e2) -> naturalOrderComparator.compare(e1, e2) > 0? e2 : e1;
-        return new Object[][]{
-            {maxOp, "(e1, e2) -> naturalOrderComparator.compare(e1, e2) < 0 ? e2 : e1", true},
-            {minOp, "(e1, e2) -> naturalOrderComparator.compare(e1, e2) > 0? e2 : e1", true},
-        }; 
-    }
-    
-    @Override
-   protected Employee[] bases(int size){
-        return new Employee[]{createEmployee()};
-    }
-
-    @Override
-    protected Collection<Employee> generate(int size) {
-        Collection<Employee> col = createEmptyCollection();
-        for (int i = 0; i < size; i++) {
-            col.add(createEmployee(String.valueOf(i + 1)));
-        }
-        return col;
-    }
-    
-    private Employee createEmployee(String id)  {
-        BiFunction<Integer, Integer, Integer> RANDOM_INT_BETWEEN
-            = (start, end) -> start + rand.nextInt(end - start);
-        int birthday = RANDOM_INT_BETWEEN.apply(Employee.MIN_BIRTHDAY, Employee.MAX_BIRTHDAY);
-        Boolean gender = rand.nextBoolean();
-        double pay = RANDOM_INT_BETWEEN.apply(Employee.MIN_PAY, Employee.MAX_PAY);
-        Employee.Title title = Employee.Title.values()[rand.nextInt(Employee.Title.values().length)];
-        return new Employee(id, birthday, gender, pay, title);
-    }
-
-    private Employee createEmployee()  {
-        return this.createEmployee(StringUtilities.randomNumeric(Employee.ID_LENGTH));
-    }
-
-    @Override
-    protected Object[] validArrayGeneratorAndDesc() {
-        return new Object[]{
-            new IntFunction[]{(IntFunction)Employee[]::new, (IntFunction)Object[]::new},
-            "{Employee[]::new, Object[]::new}"
-        };
-    }
-
-    @Override
-    protected Object[][] invalidArrayGeneratorAndDesc() {
-        return new Object[][]{
-            {(IntFunction)Employee.Rule[]::new, "Employee.Rule[]::new"},
-            {(IntFunction)String[]::new, "String[]::new"},
-        };
-    }
-
-    @Override
-    protected IntFunction<Employee> createFunction() {
-        return i -> createEmployee(String.valueOf(i));
-    }
-
-    @Override
-    protected ToIntFunction<Employee> intValueFunction() {
-        return  e -> Integer.parseInt(e.getId()) ;
-    }
-}
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Basic test for Stream<Employee>
+ * @library /sqeutil
+ * @(#) EmployeeStreamTest.java
+ * @author Eric Wang/Tristan Yan
+ * @run testng/othervm -mx2g EmployeeStreamTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.ToIntFunction;
+import java.util.stream.IntStream;
+import org.testng.annotations.Factory;
+
+class Employee implements Comparable<Employee>, Cloneable,  java.io.Serializable {
+    private static final long serialVersionUID =  3241619007641335109L;
+
+    static final int ID_LENGTH = 6;
+    static final int MIN_BIRTHDAY = 1900;
+    static final int MAX_BIRTHDAY = 2050;
+    static final int MIN_PAY = 1000;
+    static final int MAX_PAY = 100000;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    } 
+        
+    public int getBirthday() {
+        return birthday;
+    }
+
+    public boolean isMale() {
+        return male;
+    }
+
+    public double getPay() {
+        return pay;
+    }
+
+    public void setPay(double pay) {
+        this.pay = pay;
+    }  
+
+    public Title getTitle() {
+        return title;
+    }
+
+    public void setTitle(Title title) {
+        this.title = title;
+    }
+    public Employee(String id, int birthday, boolean male, double pay, Title title) {
+        this.id = id;
+        this.birthday = birthday;
+        this.male = male;
+        this.pay = pay;
+        this.title = title;
+    }
+
+    static enum Title {
+        SE, SSE, PSE, CSE, ARCHITECT, M1, M2, M3, M4
+    }
+
+    static enum Rule {
+        ID {
+            @Override
+            Function<Employee, String> empFunc() {
+                return Employee::getId;
+            }
+            @Override
+            String funcName(){
+                return "Employee::getId";
+            }
+        },
+        BIRTHDAY {
+            @Override
+            Function<Employee, Integer> empFunc() {
+                return Employee::getBirthday;
+            }
+            @Override
+            String funcName(){
+                return "Employee::getBirthday";
+            }
+        },
+        MALE {
+            @Override
+            Function<Employee, Boolean> empFunc() {
+                return Employee::isMale;
+            }
+            @Override
+            String funcName(){
+                return "Employee::isMale";
+            }
+        },
+        PAY {
+            @Override
+            Function<Employee, Double> empFunc() {
+                return Employee::getPay;
+            }
+            @Override
+            String funcName(){
+                return "Employee::getPay";
+            }
+        },
+        TITLE {
+            @Override
+            Function<Employee, Title> empFunc(){
+                return Employee::getTitle;
+            }
+
+            @Override
+            String funcName(){
+                return "Employee::getTitle";
+            }
+        };
+
+        Comparator<Employee> getComparator() {
+            return Comparator.comparing(empFunc());
+        }
+
+        Object getValue(Employee e) { return empFunc().apply(e); }
+
+        abstract String funcName();
+        
+        abstract Function<Employee, ? extends Comparable> empFunc();
+    }
+ 
+    private String id;
+    private final int birthday;
+    private final boolean male;
+    private double pay;
+    private Title title;
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof Employee) {
+            Employee compared = (Employee) other;
+            return id.equals(compared.getId()) && birthday == compared.getBirthday()
+                    && male == compared.isMale() && pay == compared.getPay()
+                    && title == compared.getTitle();
+        } 
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.id);
+    }
+
+    @Override
+    public int compareTo(Employee t) {
+        return id.compareTo(t.getId());
+    }
+
+    @Override
+    public Employee clone() {
+        try {
+            return (Employee)super.clone();
+        } catch (CloneNotSupportedException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "id=" + getId() + ", birthday=" + getBirthday() + ". male=" + isMale()
+                + ", pay=" + getPay() + ", title=" + getTitle();
+    }
+}
+
+public class EmployeeStreamTest<T extends Collection<Employee>> extends
+            GenericStreamTest<Employee, Collection<Employee>> {
+    private final static HashMap<Boolean, Map<Integer, Employee[]>> cache = new HashMap<>();
+
+    static {
+        Function<String, Employee> strToEmployee = EmployeeStreamTest::createEmployee;
+        Function<Integer, String> lensToString = StringUtilities::randomNumeric;
+        Function<Integer, Employee> lensToEmployee = lensToString.andThen(strToEmployee);
+        BiFunction<Boolean, Integer, Employee> randomLenToEmployee = (random, len) ->
+             lensToEmployee.apply(random ? rand.nextInt(len) + 1 : len);
+        Function<Boolean, Function<Integer, Employee[]>> randomToEmployeesFunction = random -> 
+                (size -> IntStream.rangeClosed(1, size).mapToObj(len -> 
+                        randomLenToEmployee.apply(random, len)).toArray(Employee[]::new));
+        initCache(cache, randomToEmployeesFunction,  "EmployeeStreamTest");
+    }
+    public EmployeeStreamTest(Class clazz, 
+            ParallelType parallelType, int initSize) {
+        super(clazz, parallelType, Comparator.naturalOrder(), initSize);
+    }
+
+    public EmployeeStreamTest(Class clazz, 
+            ParallelType parallelType) {
+        super(clazz, parallelType, Comparator.naturalOrder());
+    }
+
+    @Factory
+    public static Object[] create(){
+      TripleFunction<Class,ParallelType,Integer, EmployeeStreamTest> supplierWithInitSize =
+              EmployeeStreamTest<Collection<Employee>>::<Class,ParallelType,Integer>new;
+      BiFunction<Class,ParallelType,EmployeeStreamTest> supplier =
+              EmployeeStreamTest<Collection<Employee>>::<Class,ParallelType>new;
+      return GenericStreamTest.create(supplierWithInitSize, supplier, true);
+    }
+
+    @Override
+    public String getTestName() {
+        return typeObject.getName() + "<Employee>";
+    }
+
+    @Override
+    protected Object[] predicateAndDesc(int size) {
+        Employee limit = createEmployee();
+        boolean isUp = rand.nextBoolean();
+        Employee.Rule rule = Arrays.stream(Employee.Rule.values()).findAny().get();
+        return new Object[]{ LambdaUtilities.randomGenericPredicate(isUp, limit, rule.getComparator()), 
+                String.format("emp -> Comparator.comparing(%s).compare(emp, %s) %s 0", rule.funcName(), isUp ? ">=" : "<", limit)};
+    }
+    
+    //Function<U, ? extends Comparable>, descrption for Function<? extends Comparable>
+    @Override
+    protected Object[][] functionAndDesc(){
+            return Arrays.stream(Employee.Rule.values()).map(rule -> new Object[]{rule.empFunc(), rule.funcName()})
+                    .toArray(Object[][]::new);   
+    }
+   
+    //BinaryOperator, descrption, stateless
+    @Override
+    protected Object[][] binaryOperatorAndDesc() {
+        BinaryOperator<Employee> maxOp = (e1, e2) -> getNaturalOrderComparator().compare(e1, e2) < 0 ? e2 : e1;
+        BinaryOperator<Employee> minOp =  (e1, e2) -> getNaturalOrderComparator().compare(e1, e2) > 0? e2 : e1;
+        return new Object[][]{
+            {maxOp, "(e1, e2) -> naturalOrderComparator.compare(e1, e2) < 0 ? e2 : e1", true},
+            {minOp, "(e1, e2) -> naturalOrderComparator.compare(e1, e2) > 0? e2 : e1", true},
+        }; 
+    }
+    
+    @Override
+   protected Employee[] bases(int size){
+        return new Employee[]{createEmployee()};
+    }
+    
+    private static Employee createEmployee(String id)  {
+        BiFunction<Integer, Integer, Integer> RANDOM_INT_BETWEEN
+            = (start, end) -> start + rand.nextInt(end - start);
+        int birthday = RANDOM_INT_BETWEEN.apply(Employee.MIN_BIRTHDAY, Employee.MAX_BIRTHDAY);
+        Boolean gender = rand.nextBoolean();
+        double pay = RANDOM_INT_BETWEEN.apply(Employee.MIN_PAY, Employee.MAX_PAY);
+        Employee.Title title = Employee.Title.values()[rand.nextInt(Employee.Title.values().length)];
+        return new Employee(id, birthday, gender, pay, title);
+    }
+
+    private Employee createEmployee()  {
+        return this.createEmployee(StringUtilities.randomNumeric(Employee.ID_LENGTH));
+    }
+
+    @Override
+    protected Object[] validArrayGeneratorAndDesc() {
+        return new Object[]{
+            new IntFunction[]{(IntFunction)Employee[]::new, (IntFunction)Object[]::new},
+            "{Employee[]::new, Object[]::new}"
+        };
+    }
+
+    @Override
+    protected Object[][] invalidArrayGeneratorAndDesc() {
+        return new Object[][]{
+            {(IntFunction)Employee.Rule[]::new, "Employee.Rule[]::new"},
+            {(IntFunction)String[]::new, "String[]::new"},
+        };
+    }
+
+    @Override
+    protected IntFunction<Employee> createFunction() {
+        return i -> createEmployee(String.valueOf(i));
+    }
+
+    @Override
+    protected ToIntFunction<Employee> intValueFunction() {
+        return  e -> Integer.parseInt(e.getId()) ;
+    }
+
+    @Override
+    protected Employee[] getArray(int size, boolean random) { return cache.get(random).get(size);  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/FilterTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class FilterTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public FilterTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+    
+    @Test(dataProvider="collectionDualPredicateData")
+    public void testFilter(String desc, Collection<U> col, Predicate<U> p1, Predicate<U> p2)  {
+        //Filter the data, check if it works as expected.
+        Collection<U> filteredColByP1 = streamFor(col).filter(p1)
+                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
+        assertTrue(verifyMatch(filteredColByP1, p1, true));
+
+        //filter on parallel stream can cause IllegalStateException
+        Collection<U>  filteredColByAlwaysTrue = streamFor(col).filter(p1).filter(e -> true)
+                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
+        assertTrue(verifyMatch(filteredColByAlwaysTrue, p1, true));
+
+        //filter with false will get nothing
+        Collection<U>  filteredColByAlwaysFalse = streamFor(col).filter(p1).filter(e -> false)
+                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
+        assertTrue(filteredColByAlwaysFalse.isEmpty());
+
+        //The reason conver l to sorted is CopyOnWriteArrayList doesn't support
+        //sort, we use ArrayList sort data instead
+        Collection<U> filteredColByP2AfterP1 = streamFor(col).filter(p1).filter(p2)
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+
+        List<U> filteredColByrP1AndP2 = streamFor(col).filter(p1.and(p2))
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+        assertEqualContents(filteredColByP2AfterP1, filteredColByrP1AndP2, test.getNaturalOrderComparator());
+
+        List<U> filteredColByrP1OrP2 = streamFor(col).filter(p1.or(p2))
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+
+        List<U> filteredExpected = new ArrayList<>(filteredColByrP1AndP2);
+        filteredExpected.addAll(filteredColByrP1OrP2);
+
+        //concat stream.filter(p1) with stream.filter(p2) should be same as stream.filter(p1 && p2) combine with 
+        //stream.filter(p1 || p2) 
+        List<U> filteredColByP1CancatfilteredColByP2 = Stream.concat(streamFor(col).filter(p1), streamFor(col).filter(p2))
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+        assertEqualContents(filteredColByP1CancatfilteredColByP2, filteredExpected, test.getNaturalOrderComparator());
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/FindTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class FindTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public FindTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionData")
+    public void testFind(String desc, Collection<U> col) {
+        Stream<U> stream = streamFor(col);
+        Optional<U> opAny = stream.findAny();
+        Optional<U> opFirst = streamFor(col).findFirst();
+        if(!stream.isParallel())
+            assertEquals(opAny, opFirst);
+        assertTrue(opAny.isPresent());
+        assertTrue(opFirst.isPresent());
+
+        assertFalse(streamFor(createEmptyCollection()).findAny().isPresent());
+        assertFalse(streamFor(createEmptyCollection()).findFirst().isPresent());
+    }
+    
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testFindNull() {
+        Collection<U> nullCol = createEmptyCollection();
+        nullCol.add(null);
+        streamFor(nullCol).findAny();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/FlatMapTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class FlatMapTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public FlatMapTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionDataWithSelection", threadPoolSize = 3)
+    public void testFlatMap(String desc, Collection<U> col, Function<U, Stream<U>> mapper) {
+        List<U> result = streamFor(col).flatMap(mapper).collect(Collectors.<U>toList());
+        verifyFlatMap(col, result, mapper);
+        
+        assertEquals(streamFor(createEmptyCollection()).flatMap(mapper).count(), 0);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ForEachTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class ForEachTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ForEachTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+       
+    @Test(dataProvider="collectionData")
+    public void testForEach(String desc, Collection<U> col) {
+        List<U> expected= new ArrayList<>(col);
+        //Unordered streams could play parallel executions, which we need a 
+        //thread-safe queue to check the data  
+        ConcurrentLinkedQueue<U> forEachQueue = new ConcurrentLinkedQueue<>();
+        streamFor(col).forEach(forEachQueue::add);
+        assertEqualContents(forEachQueue, expected, test.getNaturalOrderComparator());
+
+        List<U> forEachOrderedList = new ArrayList<>();
+        streamFor(col).forEachOrdered(forEachOrderedList::add); 
+        assertEquals(forEachOrderedList, expected);
+        
+        List<U> expectedEmpty = new ArrayList<>();
+        streamFor(createEmptyCollection()).forEach(expectedEmpty::add);
+        assertTrue(expectedEmpty.isEmpty());
+    }
+}
\ No newline at end of file
--- a/test/java/util/stream/Stream/GenericStreamTest.java	Tue Aug 27 12:38:34 2013 +0200
+++ b/test/java/util/stream/Stream/GenericStreamTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -21,6 +21,10 @@
  * questions.
  */
 
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.function.BiFunction;
@@ -30,37 +34,15 @@
 import java.util.function.Predicate;
 import java.util.function.ToIntFunction;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 import java.util.stream.Stream;
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
 import org.testng.ITest;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
 
-public abstract class GenericStreamTest<U, V extends Collection<U>> implements ITest{
-    protected enum ParallelType { Parallel, Sequential, Default }
+public abstract class GenericStreamTest<U, V extends Collection<U>>  
+            extends BaseStreamTest implements ITest {
+    protected final static int DEFAULT_INIT_SIZE = -1;
 
-    protected enum Selection { EMPTY, SINGLE, TRIANGLE, COPY_64}
-
-    //Test data size
-    protected final static int VERY_SMALL_DATA_SIZE = 1;
-    
-    protected final static int SMALL_DATA_SIZE = 1 << 2;
-
-    //MIN_PARTITION
-    protected final static int PARTITION_DATA_SIZE = 1 << 4;
-    
-    protected final static int MEDIUM_DATA_SIZE = 1 << 7;
-    
-    protected final static int SIXTY_FOUR = 64;
-    
-    protected final static int DEFAULT_INIT_SIZE = -1;
-    
-    protected final static Random rand = new Random(433494437);
-
-    private final static Class[] defaultConstructorClazz = {
+    protected final static Class[] defaultConstructorClazz = {
         ArrayDeque.class,
         ArrayList.class,
         ConcurrentLinkedDeque.class,
@@ -76,7 +58,7 @@
         Vector.class
     };
 
-    private final static Class[] capacityConstructorClazz = {
+    protected final static Class[] capacityConstructorClazz = {
         ArrayBlockingQueue.class,
         ArrayDeque.class,
         ArrayList.class,
@@ -87,7 +69,7 @@
         Vector.class
     };
 
-    private final static Class[] defaultComparableConstructorClazz = {
+    protected final static Class[] defaultComparableConstructorClazz = {
         //Sorted collection only supports Comparable data type    
         PriorityBlockingQueue.class,
         PriorityQueue.class,
@@ -95,66 +77,89 @@
         TreeSet.class,
     };
 
-    private final static Class[] capacityComparableConstructorClazz = {
+    protected final static Class[] capacityComparableConstructorClazz = {
         //Sorted collection only supports Comparable data type
         PriorityBlockingQueue.class,
         PriorityQueue.class,
     };
 
+    private final HashMap<Function<U, Stream<U>>, String> flatMappers(){
+        HashMap<Function<U, Stream<U>>, String> map = new HashMap<>();
+        map.put(e -> Stream.empty(), "e -> Stream.empty()");
+        map.put(e -> Collections.singletonList(e).stream(), 
+                "e -> Collections.singletonList(e).stream()");
+        map.put(e -> Stream.generate(() -> e).limit(SIXTY_FOUR), 
+                "e -> Stream.generate(() -> e).limit(FIFTEEN)");
+        return map;
+    }
+   
     protected final Class<V> typeObject;
 
     private final int initSize;
-
-    protected final ParallelType parallelType;
     
     protected final Comparator<U> naturalOrderComparator;
 
-    protected Stream<U> streamFor(Collection<U> c1) {
-        return (parallelType == ParallelType.Parallel) ? 
-                c1.parallelStream(): (parallelType == ParallelType.Sequential)
-                ? c1.parallelStream().sequential() : c1.stream();
+    public Stream<U> streamFor(Collection<U> c1) {
+        return (getParallelType() == ParallelType.Parallel) ? 
+            c1.parallelStream(): (getParallelType() == ParallelType.Sequential)
+            ? c1.parallelStream().sequential() : c1.stream();
     }
-    protected Collection<U> createEmptyCollection() {
+
+    public Collection<U> createEmptyCollection() {
         try {
-            Collection<U> emptyCol = (initSize == DEFAULT_INIT_SIZE) ? LambdaUtilities.create(typeObject) : 
-                                    LambdaUtilities.create(typeObject, initSize);
+            Collection<U> emptyCol = (initSize == DEFAULT_INIT_SIZE) ? 
+                LambdaUtilities.create(typeObject) : 
+                LambdaUtilities.create(typeObject, initSize);
             return emptyCol;
         } catch ( ReflectiveOperationException roe) {
             throw new RuntimeException(roe);
         }
     }
 
-    @FunctionalInterface
-    public interface TripleFunction<L, M, N, I> { 
-        public I apply(L l, M m, N n);
-    }
-
-    public static Object[] create(TripleFunction<Class, ParallelType, Integer,? extends GenericStreamTest>
-            testCreatorWithInitSize, BiFunction<Class, ParallelType, ? extends GenericStreamTest> testCreator,boolean comparable) {
-        List<GenericStreamTest> result = new ArrayList<>();
-
-        for(final ParallelType parallelType : ParallelType.values()) {
-            Arrays.stream(defaultConstructorClazz).forEach(
-                clazz ->  { result.add(testCreator.apply(clazz, parallelType)); }
-            ); 
-            if(comparable)
-              Arrays.stream(defaultComparableConstructorClazz).forEach(
-                    clazz -> result.add(testCreator.apply(clazz, parallelType)));
-
-            Arrays.stream(capacityConstructorClazz).forEach(
-                clazz -> { result.add(testCreatorWithInitSize.apply(clazz, parallelType, MEDIUM_DATA_SIZE)); }
-            );
-            if(comparable)
-              Arrays.stream(capacityComparableConstructorClazz).forEach(
-                    clazz -> result.add(testCreatorWithInitSize.apply(clazz, parallelType, MEDIUM_DATA_SIZE)));
-        }
+    public static Object[] create(TripleFunction<Class, ParallelType, Integer,
+        ? extends GenericStreamTest> testCreatorWithInitSize, 
+            BiFunction<Class, ParallelType, ? extends GenericStreamTest> 
+                testCreator, boolean comparable) {
+        List<OperatorTest> result = new ArrayList<>();
+        List<Function<GenericStreamTest, ? extends OperatorTest>> functions = 
+            Arrays.stream(OperatorTest.GenericOperatorType.values()).
+                map(OperatorTest.GenericOperatorType::getConstructor).
+                collect(Collectors.<Function<GenericStreamTest, ? extends OperatorTest>>toList());
+        if(comparable)
+            functions.add(SortedTestForCompable::new);
+        else
+            functions.add(SortedTestForNonCompable::new);
+        Arrays.stream(ParallelType.values()).forEach(parallelType -> {
+            functions.stream().forEach(function -> {
+                Arrays.stream(defaultConstructorClazz).forEach( clazz ->  { 
+                    result.add(function.apply(testCreator.apply(
+                        clazz, parallelType)));
+                }); 
+                Arrays.stream(capacityConstructorClazz).forEach( clazz -> { 
+                    result.add(function.apply(testCreatorWithInitSize.apply(
+                        clazz, parallelType, MEDIUM_DATA_SIZE)));
+                    });
+                if(comparable) {
+                    Arrays.stream(defaultComparableConstructorClazz).forEach(
+                        clazz -> { 
+                            result.add(function.apply(testCreator.apply(
+                                clazz, parallelType)));
+                        });
+                    Arrays.stream(capacityComparableConstructorClazz).forEach(
+                        clazz -> { 
+                            result.add(function.apply(testCreatorWithInitSize.
+                                apply(clazz, parallelType, MEDIUM_DATA_SIZE)));
+                        });
+                }
+            });
+        });
         return result.toArray();
     }
 
     protected GenericStreamTest(Class<V> clazz, ParallelType parallelType,
             Comparator<U> naturalOrderComparator, int initSize) {
+        super(parallelType);
         this.typeObject = clazz;
-        this.parallelType = parallelType;
         this.naturalOrderComparator = naturalOrderComparator;
         this.initSize = initSize;
     }
@@ -175,124 +180,40 @@
         for(int i = 0; i < result1.size(); i++)
             assertEquals(comparator.compare(a.get(i), b.get(i)), 0);
     }
+    
+    protected static <T> void initCache(HashMap<Boolean, Map<Integer, T[]>> 
+            cache, Function<Boolean, Function<Integer, T[]>> randomToObjecstFunc,
+            String testName){
+        Arrays.asList(true, false).forEach(isRandom -> {
+            Function<Integer, T[]> sizeToObjects = randomToObjecstFunc.apply(isRandom);
+            cache.put(isRandom, Arrays.stream(MEDIUM_DATA_SIZES).boxed().collect(Collectors.
+                <Integer, Integer, T[]>toMap(Function.identity(), sizeToObjects)));
+        });
 
-    private U getMaxOrMinWithIterator(Collection<U> col, Comparator<U> c, boolean isMax) {
-        assert(!col.isEmpty());
-        Iterator<U> it = col.iterator();
-        U choosen = it.next();
-        while(it.hasNext()) {
-            U next = it.next();
-            if (!(c.compare(choosen, next) < 0 ^ isMax)) choosen = next;
-        }
-        return choosen;
-    }
-
-    private U getMaxOrMinByCollectorBy(Collection<U> col, Comparator<U> c, boolean isMax) {
-        assert(!col.isEmpty());
-        U choosen = isMax ? streamFor(col).collect(Collectors.<U>maxBy(c)).get() :
-                streamFor(col).collect(Collectors.<U>minBy(c)).get();
-        return choosen;
-    }
-    
-    private U getMaxOrMinByReduce(Collection<U> col, Comparator<U> c, boolean isMax) {
-        assert (!col.isEmpty());
-        Optional<U> choosen = col.stream().reduce(isMax ? 
-                LambdaUtilities.maxGenericBinaryOperator(c) :
-                LambdaUtilities.minGenericBinaryOperator(c) );
-        assert(choosen.isPresent());
-        return choosen.get();
-    }
-
-    private U getMaxOrMinReduceWithBase(Collection<U> col, Comparator<U> c, boolean isMax) {
-        assert (!col.isEmpty());
-        U any = col.iterator().next();
-        U choosen = col.stream().reduce(any, 
-                isMax ? LambdaUtilities.maxGenericFunction(c) : LambdaUtilities.minGenericFunction(c),
-                isMax ? LambdaUtilities.maxGenericBinaryOperator(c) : LambdaUtilities.minGenericBinaryOperator(c));
-        return choosen;
-    }
-
-    private U getMaxOrMinCollectWithReducing(Collection<U> col, Comparator<U> c, boolean isMax) {
-        assert (!col.isEmpty());
-        U choosen = col.stream().collect(Collectors.<U>reducing(isMax ? 
-                LambdaUtilities.maxGenericBinaryOperator(c) :
-                LambdaUtilities.minGenericBinaryOperator(c))).get();
-        return choosen;
-    }
-
-    private void verifySlice(Collection<U> col, Collection<U> subL, int skip, int limit, boolean ordered) {
-        int toIndex = skip + limit < col.size() ? skip + limit : col.size();
-        if (ordered) {
-            assertEquals(new ArrayList(col).subList(skip, toIndex), subL);
-        } else {
-            // Unordered: verify that all items from the slice are
-            // present in the original collection
-            assertTrue(col.containsAll(subL));
-            assertEquals(subL.size(), toIndex - skip); 
+        try(ObjectOutputStream cacheOOS = new ObjectOutputStream(Files.
+            newOutputStream(FileSystems.getDefault().getPath(
+            System.getProperty("test.classes", "."), testName + ".cache")))) {
+            cacheOOS.writeObject(cache);
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
         }
     }
 
-    private Function<U, Stream<U>> genFlatMapper(Selection selection) {
-        switch(selection) {
-            case EMPTY: return e -> Stream.empty();
-            case SINGLE: return e -> Collections.singletonList(e).stream();
-            case TRIANGLE:  
-                return e ->  triangleStream(e);
-            case COPY_64:
-            default:
-                return e ->  Stream.generate(() -> e).limit(SIXTY_FOUR);
-        }
-    } 
-    private void verifyFlatMap(Collection<U> orig, Collection<U> result, Selection selection) {
-        switch (selection) {
-        case EMPTY:
-            assertEquals(result.size(), 0);
-            break;
-        case SINGLE:
-            assertEqualContents(new ArrayList<>(orig), result, naturalOrderComparator);
-            break;
-        case TRIANGLE:
-            List<U> list2 = new ArrayList<>();
-            orig.stream().forEach((current) -> {
-                triangleStream(current).forEach(u -> list2.add(u));
-            });
-            assertEqualContents(list2, result, naturalOrderComparator);
-            break;
-        case COPY_64:
-        default:
-            List<U> list3 = new ArrayList<>();
-            orig.stream().forEach((current) -> {
-                IntStream.range(0, SIXTY_FOUR).forEach(i -> list3.add(current));
-            });
-            assertEquals(list3, result);
-            break;
-        }
+    protected abstract U[] getArray(int size, boolean random);
+    
+    protected Collection<U> generate(int size, boolean random) {
+        Collection<U> col = createEmptyCollection();
+        Arrays.stream(getArray(size, random)).forEach(col::add);   
+        return col;
     }
-
-    private boolean verifyMatch(Collection<U> col, Predicate<U> predicate, boolean checkAll) {
-        for(U current : col) {
-            if (checkAll ^ predicate.test(current) )
-                    return !checkAll;
-        }
-        return checkAll;
-    }
-
-    private void verifyAfterMap(Collection<U> origCol, Object[] result, Function<U, ? extends Object> mapFunc) {
-        int index = 0;
-        assertEquals(origCol.size(), result.length);
-        for(U element : origCol) 
-            assertEquals(mapFunc.apply(element), result[index++]);
-    }
-
-    protected abstract  Collection<U> generate(int size);
     
     //Predicate<U>, descrption for Predicate<U>
     protected abstract  Object[] predicateAndDesc(int size);
     
-    //BinaryOperator<U>, descrption for BinaryOperator<U>, stateless
+    //BinaryOperator<U>, descrption for BinaryOperator, stateless
     protected abstract  Object[][] binaryOperatorAndDesc();
 
-    //Function<U, ? extends Comparable>, descrption for Function<? extends Comparable>
+    //Function<U, ? extends Comparable>, descrption for Function
     protected abstract  Object[][] functionAndDesc();
     
     //IntFunction<W>[], descrption for all IntFunction<W>
@@ -301,41 +222,39 @@
     //IntFunction<W>[], descrption for IntFunction<W>
     protected abstract  Object[][] invalidArrayGeneratorAndDesc();
 
-    //IntFunction<U>
+    //IntFunction<U> a generator from U to int
     protected abstract IntFunction<U> createFunction();
  
-    //ToIntFunction<U>
+    //ToIntFunction<U> a generator from int to U
     protected abstract ToIntFunction<U> intValueFunction();
-
-    //base object based on size
+    
+    private final Function<int[], Object[]> sizeRoBuilders = sizes -> 
+        Arrays.stream(sizes).boxed().flatMap(size -> 
+            Arrays.asList(true, false).stream().map(random -> generate(size, random))
+            ).toArray();
+    
+    //base object based on size, base object will be used when the operation like reduce
     protected abstract U[] bases(int size);
 
     protected Object[] builders() {
-        return new Object[]{
-            generate(MEDIUM_DATA_SIZE),
-            generate(SMALL_DATA_SIZE),
-            generate(PARTITION_DATA_SIZE),
-            generate(VERY_SMALL_DATA_SIZE)
-        };
+        return sizeRoBuilders.apply(MEDIUM_DATA_SIZES);
     }
 
     protected Object[] smallSizeBuilders() {
-        return new Object[]{
-            generate(SMALL_DATA_SIZE),
-            generate(PARTITION_DATA_SIZE),
-            generate(VERY_SMALL_DATA_SIZE)
-        };
+        return sizeRoBuilders.apply(SMALL_DATA_SIZES);
     }
 
-    //Test only needs Collection<U>
-    @DataProvider
-    protected Iterator<Object[]> collectionData() {    
-        return Arrays.stream(builders()).map(data ->
-                new Object[]{String.format("%s(%d)", typeObject.getName(), ((Collection<U>)data).size()),data}).iterator();
+    //Test only needs Collection<U>, test like find, count, forEach, subStream, 
+    //sorted test need this
+    protected Iterator<Object[]> collectionData() {
+        Function<Collection<U>, Object[]> objGenerator = data -> new Object[]{
+            String.format("%s(%d)", typeObject.getName(), data.size()),data};
+       return Arrays.stream(builders()).
+               map(data -> objGenerator.apply((Collection<U>)data)).iterator();
     }
     
-    //Test only needs Collection<U>
-    @DataProvider
+    //Test only needs Collection<U> and invalid index, test like 
+    // testSubstreamException needs this.
     protected Iterator<Object[]> collectionStartEndData() {
         List<Object[]> dataList= new ArrayList<>();
         long[][] exceptionStartEnd = new long[][]{
@@ -343,33 +262,36 @@
             {1, -1},   //endInclusive is negative
             {1, 0}    //startInclusive is greater than endExclusive
         };
+       TripleFunction<Collection<U>, Long, Long, Object[]> objGenerator = 
+            (data, start, end) ->  new Object[]{String.format("%s(%d), %d, %d", 
+                typeObject.getName(), data.size(), start, end),
+                    data, start, end};
        Arrays.stream(builders()).forEach(data -> {
-           Collection<U> col = (Collection<U>)data;
            Arrays.stream(exceptionStartEnd).forEach(startEnd -> {
-               dataList.add(new Object[]{String.format("%s(%d), %d, %d", typeObject.getName(), col.size(), startEnd[0], 
-                       startEnd[1]), col, startEnd[0], startEnd[1]});
+               dataList.add(objGenerator.apply((Collection<U>)data, startEnd[0], 
+                       startEnd[1]));
            });
        });    
        return dataList.iterator();
     }
 
-    //Test needs Collection<U> and one Predicate
-    @DataProvider
+    //Test needs Collection<U> and one Predicate, tests like collect by 
+    // partition, anyMatch, noneMatch, allMatch needs this
     protected Iterator<Object[]> collectionPredicateData() {
         List<Object[]> dataList= new ArrayList<>();
         Arrays.stream(builders()).forEach(data -> {
             Collection<U> col = (Collection<U>)data;
             Object[] predicateAndDesc = predicateAndDesc(col.size());
             Predicate<U> p = (Predicate<U>)predicateAndDesc[0];
-            String desc = String.format("%s(%d), %s", typeObject.getName(), col.size(), (String)predicateAndDesc[1]);
+            String desc = String.format("%s(%d), %s", typeObject.getName(), 
+                    col.size(), (String)predicateAndDesc[1]);
             dataList.add(new Object[]{desc, data, p});
         });
         return dataList.iterator();
     }
     
-    //Test needs Collection<U> and two Predicate
-    @DataProvider
-    protected Iterator<Object[]> collectionDualPredicateData() {
+    //Test needs Collection<U> and two Predicates, test like filter needs this.
+    public Iterator<Object[]> collectionDualPredicateData() {
         List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(data -> {
             Collection<U> col = (Collection<U>)data;
@@ -377,15 +299,16 @@
             Object[] predicateAndDesc2 = predicateAndDesc(col.size());
             Predicate<U> p1 = (Predicate<U>)predicateAndDesc1[0];
             Predicate<U> p2 = (Predicate<U>)predicateAndDesc2[0];
-            String desc = String.format("%s(%d), %s, %s", typeObject.getName(), col.size(), 
-                    (String)predicateAndDesc1[1], (String)predicateAndDesc2[1]);
+            String desc = String.format("%s(%d), %s, %s", typeObject.getName(), 
+                col.size(),(String)predicateAndDesc1[1], 
+                (String)predicateAndDesc2[1]);
             dataList.add(new Object[]{desc, col, p1, p2});
         });
         return dataList.iterator();
     }
     
-    //Test needs Collection<U>, U base and and BinaryOperator<U>, stateless
-    @DataProvider
+    //Test needs Collection<U>, U base and and BinaryOperator<U>, stateless, 
+    //test like reduce needs this.
     protected Iterator<Object[]> collectionBinaryOpeatorData(){
         List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(data -> {
@@ -395,16 +318,17 @@
                 String boDesc = (String)bpDesc[1];
                 boolean stateless =  (Boolean)bpDesc[2];
                 Arrays.stream(bases(col.size())).forEach(base -> {
-                    dataList.add(new Object[]{String.format("%s(%d), %s, %s, %s", typeObject.getName(), col.size(), base, 
-                            boDesc, stateless), col, base, bo, stateless});
+                    dataList.add(new Object[]{String.format("%s(%d), %s, %s, %s",
+                        typeObject.getName(), col.size(), base, 
+                        boDesc, stateless), col, base, bo, stateless});
                 });
             });
         });
         return dataList.iterator();
     }
     
-    //Test needs Collection<U>, Function<U, ? extends Object>
-    @DataProvider
+    //Test needs Collection<U>, Function<U, ? extends Object>, tests like 
+    //collect by groupingBy, max, min, sorted, peek need this
     protected Iterator<Object[]> collectionFunctionData(){
          List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(data -> {
@@ -412,16 +336,16 @@
             Arrays.stream(functionAndDesc()).forEach((Object[] funcDesc) -> {
                 Function<U, Object> func = (Function<U, Object>)funcDesc[0];
                 String desc = (String)funcDesc[1];
-                dataList.add(new Object[]{String.format("%s(%d), %s", typeObject.getName(), col.size(), desc),
-                    col, func});
+                dataList.add(new Object[]{String.format("%s(%d), %s", 
+                    typeObject.getName(), col.size(), desc), col, func});
             });
         });
         return dataList.iterator();
     }
     
-    //Test needs Collection<U>, Function<U, K> keyFunc, Function<U, V> valueFunc
+    //Test needs Collection<U>, Function<U, K> keyFunc, Function<U, V> valueFunc, 
+    //tests like collect map needs this.
     //toMap need keep key's identical, using Function.identity()
-    @DataProvider
     protected Iterator<Object[]> collectionKeyValueFunctionData(){
          List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(data -> {
@@ -429,15 +353,17 @@
             Arrays.stream(functionAndDesc()).forEach((Object[] valueFuncDesc) -> {
                 Function<U, Object> valueFunc = (Function<U, Object>)valueFuncDesc[0];
                 String valuedesc = (String)valueFuncDesc[1];
-                dataList.add(new Object[]{String.format("%s(%d), %s, %s", typeObject.getName(), col.size(), 
-                        "Function.identity()", valuedesc), col, Function.identity(), valueFunc});
+                dataList.add(new Object[]{String.format("%s(%d), %s, %s", 
+                    typeObject.getName(), col.size(), 
+                    "Function.identity()", valuedesc), col, Function.identity(), 
+                    valueFunc});
             });
         });
         return dataList.iterator();
     }
     
-    //testToArray needs Collection<U>, IntFunction<W>[] 
-    @DataProvider
+    //testToArray needs Collection<U>, IntFunction<W>[], test like toArray needs 
+    //this.
     protected Iterator<Object[]> collectionArrayGeneratorData(){
          List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(data -> {
@@ -445,410 +371,93 @@
             Object[] validArrayGenerators =  validArrayGeneratorAndDesc();
             IntFunction[] generators = (IntFunction[])validArrayGenerators[0];
             String desc = (String)validArrayGenerators[1];
-            dataList.add(new Object[]{String.format("%s(%d), %s", typeObject.getName(), col.size(), desc), col, generators});
+            dataList.add(new Object[]{String.format("%s(%d), %s", 
+                    typeObject.getName(), col.size(), desc), col, generators});
         });
         return dataList.iterator();
     }
     
-    //testToArrayException needs Collection<U>, IntFunction<W>, 
-    //This for test toArray's ArrayStoreException
-    @DataProvider
-    protected Iterator<Object[]> collectionArrayInvalidGeneratorData(){
+    //testToArrayException needs Collection<U>, IntFunction<W>,  this is for 
+    //testing toArray's ArrayStoreException
+    public Iterator<Object[]> collectionArrayInvalidGeneratorData(){
          List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(data -> {
             Collection<Integer> col = (Collection<Integer>)data;
-            Arrays.stream(invalidArrayGeneratorAndDesc()).forEach(invalidArrayGenerators -> {
-                IntFunction generator = (IntFunction)invalidArrayGenerators[0];
-                String desc = (String)invalidArrayGenerators[1];
-                dataList.add(new Object[]{String.format("%s(%d), %s", typeObject.getName(), col.size(), desc), col, generator});
+            Arrays.stream(invalidArrayGeneratorAndDesc()).forEach(
+                    generatorAndDesc -> {
+                IntFunction generator = (IntFunction)generatorAndDesc[0];
+                String desc = (String)generatorAndDesc[1];
+                dataList.add(new Object[]{String.format("%s(%d), %s", 
+                        typeObject.getName(), col.size(), desc), col, generator});
             });
         });
         return dataList.iterator();
     }
     
-    //Test needs Collection<U>, Collection<U>
-   @DataProvider
+    //Test needs two Collection<U>, operation like concat needs this.
     protected Iterator<Object[]> concatCollectionData(){
         List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(data1 ->
-                Arrays.stream(builders()).forEach(data2 -> {
-                    String desc = String.format("%s(%d), %s(%d)", typeObject.getName(), ((Collection<U>)data1).size(), 
-                            typeObject.getName(), ((Collection<U>)data2).size());
-                    dataList.add(new Object[]{desc, data1, data2}); }
-                )
+            Arrays.stream(builders()).forEach(data2 -> {
+                String desc = String.format("%s(%d), %s(%d)", 
+                        typeObject.getName(), ((Collection<U>)data1).size(), 
+                        typeObject.getName(), ((Collection<U>)data2).size());
+                dataList.add(new Object[]{desc, data1, data2}); }
+            )
          );
         return dataList.iterator();
     }
    
-    @DataProvider
-    protected Iterator<Object[]>  exceptionTestData()  throws Exception {
-        Collection<U> col = generate(SMALL_DATA_SIZE);
+   //Test like test limit's exception need this
+    protected Iterator<Object[]>  exceptionTestData()  {
+        Collection<U> col = generate(SMALL_DATA_SIZE, false);
         return Arrays.stream(new Object[][]{
             {String.format("%s(%d)", typeObject.getName(), col.size()), col},
         }).iterator();
     }
 
-    @DataProvider
+    //Test like distinct needs this.
     protected Iterator<Object[]> smallSizeCollectionData() {
         List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(smallSizeBuilders()).forEach(data -> {
             Collection<U> col = (Collection<U>)data;
-            dataList.add(new Object[]{String.format("%s(%d)", typeObject.getName(), col.size()), col});
+            dataList.add(new Object[]{String.format("%s(%d)", 
+                    typeObject.getName(), col.size()), col});
         });
         return dataList.iterator();
     }
-    
-    @DataProvider
+
     protected Iterator<Object[]> collectionDataWithLimit() {
         List<Object[]> dataList = new ArrayList<>();
         Arrays.stream(builders()).forEach(dataCol -> { 
             Collection<U> col = (Collection<U>)dataCol;
             int withBoundryLimit = rand.nextInt(col.size());
-            int beyondBoundryLimit = col.size() + rand.nextInt(Integer.MAX_VALUE - col.size());
-            dataList.add(new Object[]{String.format("%s(%d), %s", typeObject.getName(), col.size(), withBoundryLimit, 
+            int beyondBoundryLimit = col.size() 
+                    + rand.nextInt(Integer.MAX_VALUE - col.size());
+            dataList.add(new Object[]{String.format("%s(%d), %s", 
+                    typeObject.getName(), col.size(), withBoundryLimit, 
                     beyondBoundryLimit), col, withBoundryLimit, beyondBoundryLimit}); 
         });
         return dataList.iterator();
     }
 
-    @DataProvider
+    //Test like test flatMap need this
     protected Iterator<Object[]> collectionDataWithSelection() {
         List<Object[]> dataList = new ArrayList<>();
+        TripleFunction<Collection<U>, String, Function<U, Stream<U>>, 
+                Object[]> objectGenerator = (col, str , mapper) -> 
+                new Object[]{String.format("<%s(%d), %s>", typeObject.getName(),
+                col.size(), str), col, mapper};
         Arrays.stream(smallSizeBuilders()).forEach(data -> {
             Collection<U> col = (Collection<U>)data;
-            Arrays.stream(Selection.values()).forEach(selection -> {
-                dataList.add(new Object[]{String.format("%s(%d), %s", typeObject.getName(), col.size(), selection),
-                col, selection});  
-            }); 
+            flatMappers().forEach((func, msg) -> {
+                dataList.add(objectGenerator.apply(col, msg, func));
+            });
         });
         return dataList.iterator();
     }
 
-    @Test(dataProvider="collectionFunctionData")
-    public void testCollectByGroupingBy(String desc, Collection<U> col, Function<U, ? extends Object> mapFunc) {
-        Map<Object, List<U>> result = streamFor(col). collect(Collectors.<U, Object>groupingBy(mapFunc));
-        result.keySet().stream().forEach((key) -> {
-            result.get(key).stream().forEach((u) -> {
-                assertEquals(key, mapFunc.apply(u));
-            });
-        });
-        assertTrue(streamFor(createEmptyCollection()).collect(Collectors.<U, Object>groupingBy(mapFunc)).isEmpty());
+    public Comparator<U> getNaturalOrderComparator() {
+        return naturalOrderComparator;
     }
-    
-    @Test(dataProvider="collectionPredicateData")
-    public void testCollectByPartition(String desc, Collection<U> col, Predicate<U> mapFunc) {
-        Map<Boolean, List<U>> result = streamFor(col). collect(Collectors.<U>partitioningBy(mapFunc));
-        for(boolean key : result.keySet()) {
-            result.get(key).stream().forEach((u) -> {
-                assertEquals(mapFunc.test(u), key);
-            });
-        }
-        assertTrue(streamFor(createEmptyCollection()).collect(Collectors.<U>partitioningBy(mapFunc)).get(true).isEmpty());
-        assertTrue(streamFor(createEmptyCollection()).collect(Collectors.<U>partitioningBy(mapFunc)).get(false).isEmpty());
-    }
-
-    @Test(dataProvider="collectionKeyValueFunctionData")
-    public <K, V> void testCollectToMap(String desc, Collection<U> col, Function<U, K> keyFunc, Function<U, V> valueFunc) {
-        Map<K, V> keyToValue = streamFor(col).collect(Collectors.<U, K, V>toMap(keyFunc, valueFunc));
-        assertEquals(keyToValue.size(), streamFor(col).map(keyFunc).distinct().count());
-        col.stream().forEach((u) -> {
-            assertEquals(valueFunc.apply(u), keyToValue.get(keyFunc.apply(u)));
-        });
-    }
-
-    @Test(dataProvider="collectionData")
-    public void testFind(String desc, Collection<U> col) throws Exception{
-        Stream<U> stream = streamFor(col);
-        Optional<U> opAny = stream.findAny();
-        Optional<U> opFirst = streamFor(col).findFirst();
-        if(!stream.isParallel())
-            assertEquals(opAny, opFirst);
-        assertTrue(opAny.isPresent());
-        assertTrue(opFirst.isPresent());
-
-        assertFalse(streamFor(createEmptyCollection()).findAny().isPresent());
-        assertFalse(streamFor(createEmptyCollection()).findFirst().isPresent());
-    }
-       
-    @Test(dataProvider="collectionPredicateData")
-    public void testXxxMatch(String desc, Collection<U> col, Predicate<U> predicate) throws Exception {
-        assertEquals(streamFor(col).allMatch(predicate),
-                verifyMatch(col, predicate, true));
-        assertEquals(streamFor(col).anyMatch(predicate),
-                verifyMatch(col, predicate, false));
-        assertEquals(streamFor(col).noneMatch(predicate),
-                verifyMatch(col, predicate.negate(), true)); 
-
-        assertTrue(streamFor(createEmptyCollection()).allMatch(predicate));
-        assertFalse(streamFor(createEmptyCollection()).anyMatch(predicate));
-        assertTrue(streamFor(createEmptyCollection()).noneMatch(predicate));
-    }
-  
-    @Test(dataProvider="concatCollectionData")
-    public void testConcat(String desc, Collection<U> tobeConcated, Collection<U> concat) throws Exception {
-        //We're using List to store expected result because Set could merge object, 
-        Collection<U> expected = new ArrayList<>(tobeConcated);
-        expected.addAll(concat);
-
-        //test concat with parallel/non-parallel Stream
-        for(ParallelType concatType : ParallelType.values()) {
-            Stream<U> concatStream = (concatType == ParallelType.Parallel) ? 
-                concat.parallelStream(): (concatType == ParallelType.Sequential)
-                ? concat.parallelStream().sequential() : concat.stream();
-            List<U> calculated = Stream.concat(streamFor(tobeConcated), concatStream)
-                    .collect(Collectors.<U>toList());
-            assertEqualContents(calculated, expected, naturalOrderComparator);
-        }
-
-        List<U> result3 = Stream.concat(tobeConcated.stream(), streamFor(createEmptyCollection()))
-                .collect(Collectors.<U>toList());
-        List<U> result4 = Stream.concat(tobeConcated.stream(), Stream.empty())
-                .collect(Collectors.<U>toList());
-        assertEqualContents(tobeConcated, result3, naturalOrderComparator);
-        assertEqualContents(tobeConcated, result4, naturalOrderComparator);
-    }
-
-    @Test(dataProvider="collectionData")
-    public void testCount(String desc, Collection<U> col) throws Exception{
-        assertEquals(streamFor(col).count(), col.size());
-        assertEquals(streamFor(col).count(), streamFor(col).mapToLong(u -> 1).sum());
-        assertEquals(streamFor(createEmptyCollection()).count(), 0);
-    }
-
-    @Test(dataProvider="collectionDualPredicateData")
-    public void testFilter(String desc, Collection<U> col, Predicate<U> p1, Predicate<U> p2) throws Exception {
-        //Filter the data, check if it works as expected.
-        Collection<U> filteredColByP1 = streamFor(col).filter(p1)
-                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
-        assertTrue(verifyMatch(filteredColByP1, p1, true));
-
-        //filter on parallel stream can cause IllegalStateException
-        Collection<U>  filteredColByAlwaysTrue = streamFor(col).filter(p1).filter(e -> true)
-                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
-        assertTrue(verifyMatch(filteredColByAlwaysTrue, p1, true));
-
-        //filter with false will get nothing
-        Collection<U>  filteredColByAlwaysFalse = streamFor(col).filter(p1).filter(e -> false)
-                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
-        assertTrue(filteredColByAlwaysFalse.isEmpty());
-
-        //The reason conver l to sorted is CopyOnWriteArrayList doesn't support
-        //sort, we use ArrayList sort data instead
-        Collection<U> filteredColByP2AfterP1 = streamFor(col).filter(p1).filter(p2)
-                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
-
-        List<U> filteredColByrP1AndP2 = streamFor(col).filter(p1.and(p2))
-                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
-        assertEqualContents(filteredColByP2AfterP1, filteredColByrP1AndP2, naturalOrderComparator);
-
-        List<U> filteredColByrP1OrP2 = streamFor(col).filter(p1.or(p2))
-                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
-
-        List<U> filteredExpected = new ArrayList<>(filteredColByrP1AndP2);
-        filteredExpected.addAll(filteredColByrP1OrP2);
-
-        //concat stream.filter(p1) with stream.filter(p2) should be same as stream.filter(p1 && p2) combine with 
-        //stream.filter(p1 || p2) 
-        List<U> filteredColByP1CancatfilteredColByP2 = Stream.concat(streamFor(col).filter(p1), streamFor(col).filter(p2))
-                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
-        assertEqualContents(filteredColByP1CancatfilteredColByP2, filteredExpected, naturalOrderComparator);
-
-        assertEquals(streamFor(createEmptyCollection()).filter(p1).count(), 0); 
-    }
-
-    @Test(dataProvider="collectionData")
-    public void testForEach(String desc, Collection<U> col) throws Exception{
-        List<U> expected= new ArrayList<>(col);
-        //Unordered streams could play parallel executions, which we need a 
-        //thread-safe queue to check the data  
-        ConcurrentLinkedQueue<U> forEachQueue = new ConcurrentLinkedQueue<>();
-        streamFor(col).forEach(forEachQueue::add);
-        assertEqualContents(forEachQueue, expected, naturalOrderComparator);
-
-        List<U> forEachOrderedList = new ArrayList<>();
-        streamFor(col).forEachOrdered(forEachOrderedList::add); 
-        assertEquals(forEachOrderedList, expected);
-        
-        List<U> expectedEmpty = new ArrayList<>();
-        streamFor(createEmptyCollection()).forEach(expectedEmpty::add);
-        assertTrue(expectedEmpty.isEmpty());
-    }
-
-    @Test(dataProvider="collectionDataWithLimit")
-    public void testLimit(String desc, Collection<U> col, int withBoundryLimit, int beyondBoundryLimit) {
-        Collection<U> resultWithBoundary = streamFor(col).limit(withBoundryLimit)
-                .collect(Collectors.<U,List<U>>toCollection(LinkedList::new));
-        assertEquals(resultWithBoundary.size(), withBoundryLimit);
-
-        Collection<U> resultBeyondBoundary = streamFor(col).limit(beyondBoundryLimit)
-                .collect(Collectors.<U,List<U>>toCollection(LinkedList::new));
-        assertEquals(resultBeyondBoundary.size(), resultBeyondBoundary.size());
-
-        assertEquals(streamFor(createEmptyCollection()).limit(withBoundryLimit).count(), 0);
-        assertEquals(streamFor(createEmptyCollection()).limit(beyondBoundryLimit).count(), 0);
-    }
-    
-    @Test(dataProvider="exceptionTestData",expectedExceptions = IllegalArgumentException.class)
-    public void testLimitException(String desc, Collection<U> col){
-        streamFor(col).limit(-1).toArray();
-    }
-
-    @Test(dataProvider="collectionDataWithSelection")
-    public void testFlatMap(String desc, Collection<U> col, Selection selection) {
-        List<U> result = streamFor(col)
-                .flatMap(genFlatMapper(selection))
-                .collect(Collectors.<U>toList());
-        verifyFlatMap(col, result, selection);
-        
-        assertEquals(streamFor(createEmptyCollection()).flatMap(genFlatMapper(selection)).count(), 0);
-    }
-
-    @Test(dataProvider="collectionFunctionData")
-    public void testMaxAndMin(String desc, Collection<U> col, Function<U, ? extends Comparable> mapFunc) {
-        Comparator<U> comp = Comparator.comparing(mapFunc);
-        Optional<U> optionaMax = streamFor(col).max(comp) ;
-        Optional<U> optionaMin = streamFor(col).min(comp) ;
-        assertTrue(optionaMax.isPresent());
-        assertTrue(optionaMin.isPresent());
-
-        assertEquals(comp.compare(optionaMax.get(), getMaxOrMinWithIterator(col, comp, true)), 0);
-        assertEquals(comp.compare(optionaMin.get(), getMaxOrMinWithIterator(col, comp, false)), 0);
-        
-        assertEquals(comp.compare(optionaMax.get(), getMaxOrMinByCollectorBy(col, comp, true)), 0);
-        assertEquals(comp.compare(optionaMin.get(), getMaxOrMinWithIterator(col, comp, false)), 0);
-
-        assertEquals(comp.compare(optionaMax.get(), getMaxOrMinByReduce(col, comp, true)), 0);
-        assertEquals(comp.compare(optionaMin.get(), getMaxOrMinByReduce(col, comp, false)), 0);
-
-        assertEquals(comp.compare(optionaMax.get(), getMaxOrMinReduceWithBase(col, comp, true)), 0);
-        assertEquals(comp.compare(optionaMin.get(), getMaxOrMinReduceWithBase(col, comp, false)), 0);
-
-        assertEquals(comp.compare(optionaMax.get(), getMaxOrMinCollectWithReducing(col, comp, true)), 0);
-        assertEquals(comp.compare(optionaMin.get(), getMaxOrMinCollectWithReducing(col, comp, false)), 0);
-
-        assertFalse(streamFor(createEmptyCollection()).max(comp).isPresent());
-        assertFalse(streamFor(createEmptyCollection()).max(comp).isPresent());
-    }
-   
-    @Test(dataProvider="collectionBinaryOpeatorData")
-    public void testReduce(String desc, Collection<U> col, U base, BinaryOperator<U> op, boolean stateless)  {
-        Optional<U> reduceResult = streamFor(col).reduce( op);
-        assertTrue(reduceResult.isPresent());
-        Iterator<U> iter = col.iterator();
-        U expected = iter.next();
-        while(iter.hasNext())
-            expected = op.apply(expected, iter.next());
-        assertEquals(reduceResult.get(), expected);
-
-        assertEquals(streamFor(createEmptyCollection()).reduce(base,op), base);
-        assertFalse(streamFor(createEmptyCollection()).reduce(op).isPresent());
-
-        if(stateless || !streamFor(col).isParallel()) {
-            U reduceWithBaseResult = streamFor(col).reduce(base, op);
-            U expectedWithBase = base;
-            for(U aCol : col)
-                expectedWithBase = op.apply(expectedWithBase, aCol);
-            assertEquals(reduceWithBaseResult, expectedWithBase);
-        }
-    }
-            
-    @Test(dataProvider="collectionData")
-    public void testSubstream(String desc, Collection<U> col) {
-        BiFunction<Integer,Integer,Integer> bf = LambdaUtilities.randBetweenIntegerFunction();
-        int skip = rand.nextInt(col.size());
-        int limit1 = bf.apply(0, col.size() - skip);
-        Collection<U> sliceCol = streamFor(col).substream(skip, skip + limit1).
-                collect(Collectors.<U>toList());
-        verifySlice(col, sliceCol, skip, limit1, !col.getClass().equals(HashSet.class));
-
-        int limitExceeded = bf.apply(col.size() - skip, Integer.MAX_VALUE);
-        Collection<U> sliceCol2 = streamFor(col).substream(skip, skip + limitExceeded).
-                collect(Collectors.<U>toList());
-        //We couldn't predicate unordered collection exact behavior for substream, only check the length and if data
-        // exists in original collection
-        verifySlice(col, sliceCol2, skip, limitExceeded, !col.getClass().equals(HashSet.class));
-
-        assertEquals(streamFor(col).substream(skip, skip).count(), 0);
-
-        //skip exceed collection size cause empty stream
-        Stream<U> stream3 = streamFor(col);
-        int skipExceeded = bf.apply(col.size(), Integer.MAX_VALUE);
-        assertEquals(stream3.substream(skipExceeded, skipExceeded + 1).count(), 0);
-
-        assertEquals(streamFor(createEmptyCollection()).substream(skip, skip + limit1).count(), 0);
-    }
-    
-    @Test(dataProvider="collectionStartEndData",expectedExceptions = IllegalArgumentException.class)
-    public void  testSubstreamException(String desc, Collection<U> col, long startInclusive, long endExclusive){
-        streamFor(col).substream(startInclusive).count(); 
-        streamFor(col).substream(startInclusive, endExclusive).count();  
-    }
-
-    @Test(dataProvider="collectionFunctionData")
-    public void testSorted(String desc, Collection<U> col, Function<U, ? extends Comparable> mapFunc) {
-        // SortedSet instance's stream can't be reordered, we use ArrayList to do reorder
-        Comparator<U> comp = Comparator.comparing(mapFunc);
-        List<U> sorted = new ArrayList<>(col);
-        List<U> reversed = streamFor(col).sorted(comp).collect(Collectors.<U>toList());
-        Collections.sort(sorted, comp);
-        assertEquals(sorted, reversed);
-
-        assertEquals(streamFor(createEmptyCollection()).sorted(comp).count(), 0);
-    }
-
-    //Note non-Comparable U need override this method
-    @Test(dataProvider="collectionData")
-    public void testSortedSpecial(String desc, Collection<U> col) {
-        // SortedSet instance's stream can't be reordered, we use ArrayList to do reorder
-        List<U> sorted = new ArrayList<>(col);
-        List<U> reversed = streamFor(col).sorted().collect(Collectors.<U>toList());
-        Collections.sort(sorted, naturalOrderComparator);
-        assertEquals(sorted, reversed);
-
-        assertEquals(streamFor(createEmptyCollection()).sorted().count(), 0);
-    }
-
-    @Test(dataProvider="collectionFunctionData")
-    public void testPeek(String desc, Collection<U> col, Function<U, ? extends Object> mapFunc) {
-        //Note ArrayList is not a concurrent data type, if we don't set initial
-        //size, we could get AIOOBE
-        List<U> peekList = new ArrayList<>(col.size());
-        Object[] result = streamFor(col).peek(peekList::add).map(mapFunc).toArray();
-        verifyAfterMap(col, result, mapFunc);
-        
-        List<U> emptyList = new ArrayList<>();
-        assertEquals(streamFor(createEmptyCollection()).peek(emptyList::add).count(), 0);
-        assertTrue(emptyList.isEmpty());
-    }
-
-    @Test(dataProvider="collectionArrayGeneratorData")
-    public void testToArray(String desc, Collection<U> col, IntFunction[] generators) {
-        Object[] expectedArr = col.toArray();
-        assertEquals(streamFor(col).toArray(), expectedArr);
-        assertEquals(streamFor(createEmptyCollection()).toArray().length, 0);
-        
-         Arrays.stream(generators).forEach(generator -> {
-             assertEquals(streamFor(col).toArray(generator), expectedArr);
-             assertEquals(streamFor(createEmptyCollection()).toArray(generator).length, 0);
-         });
-    }
-    
-    @Test(dataProvider="collectionArrayInvalidGeneratorData",expectedExceptions = ArrayStoreException.class)
-    public void testToArrayException(String desc, Collection<U> col, IntFunction generator){
-        streamFor(col).toArray(generator);
-    }
-
-    @Test(dataProvider="smallSizeCollectionData")
-    public void testDistinct(String desc, Collection<U> col)  {
-        Set<U> set = new HashSet<>(col);
-        List<U> list = streamFor(col).flatMap(genFlatMapper(Selection.COPY_64)).distinct().collect(Collectors.<U>toList());
-        assertEqualContents(list, set, naturalOrderComparator); 
-        
-        assertEquals(streamFor(createEmptyCollection()).distinct().count(), 0);
-    }
-
-    private Stream<U> triangleStream(U u) {
-        int e = intValueFunction().applyAsInt(u);
-        return IntStream.range(0, e).mapToObj(i -> createFunction().apply(e * (e - 1) / 2 + i));
-    }
-}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/IntegerReduceTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.IntSummaryStatistics;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class IntegerReduceTest<V extends Collection<Integer>> extends
+            OperatorTest<Integer, V> {
+    public IntegerReduceTest(GenericStreamTest<Integer, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testCollectSummarizingInt(String desc, Collection<Integer> col,
+        Function<Integer, ? extends Object> mapFunc) {
+        //test summarizingInt
+        IntSummaryStatistics iss = streamFor(col).collect(
+                Collectors.<Integer>summarizingInt(Integer::intValue));
+        assertEquals(iss.getCount(), col.size());
+        assertEquals(iss.getMax(), streamFor(col).
+                max(test.getNaturalOrderComparator()).get().intValue());
+        assertEquals(iss.getMin(), streamFor(col).
+                min(test.getNaturalOrderComparator()).get().intValue());
+        assertEquals(iss.getSum(), streamFor(col).
+                mapToLong(Integer::longValue).sum());
+    }
+
+
+    @Test(dataProvider="collectionData")
+    public void testReduceIdentitiyWithoutBase(String desc, 
+            Collection<Integer> col) {
+        Optional<Integer> total = streamFor(col).reduce(
+                LambdaUtilities.addIntegerBinaryOperator());
+        double avg = (double) total.get().intValue() / col.size();
+        BigDecimal deviationSquare = streamFor(col).reduce(new BigDecimal(0.0),
+                LambdaUtilities.deviationSequareFunction(avg),  
+                LambdaUtilities.addBigDecimalBinaryOperator());
+        double stdev = deviationSquare.doubleValue() / col.size();
+
+        int totalExpected = 0;
+        for (Integer aCol : col)
+            totalExpected +=  aCol;
+        assertEquals(totalExpected, total.get().intValue());
+        double avgExpected = (double)totalExpected / col.size();
+        assertEquals(avgExpected, avg);
+
+        BigDecimal deviationSquareExpected = new BigDecimal(0.0);
+        for (Integer aCol : col)
+            deviationSquareExpected = deviationSquareExpected
+                    .add(new BigDecimal(avg - aCol).pow(2));
+        assertEquals(deviationSquare, deviationSquareExpected);
+
+        double stddvExpected 
+                = deviationSquareExpected.doubleValue() / col.size();
+        assertEquals(stddvExpected, stdev);
+    }
+}
--- a/test/java/util/stream/Stream/IntegerStreamTest.java	Tue Aug 27 12:38:34 2013 +0200
+++ b/test/java/util/stream/Stream/IntegerStreamTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -1,178 +1,173 @@
-/*
- * Copyright (c) 2012, 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.
- *
- * 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.
- */
-
-/**
- * @test
- * @summary Basic test for Stream<Integer>
- * @library /sqeutil
- * @(#) IntegerStreamTest.java
- * @author Tristan Yan
- * @run testng IntegerStreamTest
- */
-
-import java.math.BigDecimal;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.IntSummaryStatistics;
-import java.util.Optional;
-import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
-import java.util.function.Function;
-import java.util.function.IntFunction;
-import java.util.function.ToIntFunction;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-import static org.testng.Assert.assertEquals;
-import org.testng.annotations.Factory;
-import org.testng.annotations.Test;
-
-public class IntegerStreamTest<T extends Collection<Integer>> extends GenericStreamTest<Integer, Collection<Integer>> {
-    private IntegerStreamTest(Class clazz,
-            ParallelType parallelType, int initSize) {
-        super(clazz, parallelType, Comparator.naturalOrder(), initSize);
-    }
-
-   private IntegerStreamTest(Class clazz,
-            ParallelType parallelType) {
-        super(clazz, parallelType, Comparator.naturalOrder());
-    }
-
-    @Factory
-    public static Object[] create(){
-      TripleFunction<Class,ParallelType,Integer, IntegerStreamTest> supplierWithInitSize =
-              IntegerStreamTest<Collection<Integer>>::<Class,ParallelType,Integer>new;
-      BiFunction<Class,ParallelType, IntegerStreamTest> supplier =
-              IntegerStreamTest<Collection<Integer>>::<Class,ParallelType>new;
-      return GenericStreamTest.create(supplierWithInitSize, supplier, true);
-    }
-
-    @Override
-    public String getTestName() {
-        return typeObject.getName() + "<Integer>";
-    }
-
-    @Test(dataProvider="collectionFunctionData")
-    public void testCollectSummarizingInt(String desc, Collection<Integer> col, Function<Integer, ? extends Object> mapFunc) {
-        //test summarizingInt
-        IntSummaryStatistics iss = streamFor(col).collect(Collectors.<Integer>summarizingInt(Integer::intValue));
-        assertEquals(iss.getCount(), col.size());
-        assertEquals(iss.getMax(), streamFor(col).max(naturalOrderComparator).get().intValue());
-        assertEquals(iss.getMin(), streamFor(col).min(naturalOrderComparator).get().intValue());
-        assertEquals(iss.getSum(), streamFor(col).mapToInt(Integer::intValue).sum());
-    }
-
-    @Test(dataProvider="collectionData")
-    public void testReduceIdentitiyWithoutBase(String desc, Collection<Integer> col) throws Exception{
-        Stream<Integer> streamTotal = streamFor(col);
-        Optional<Integer> total = streamTotal.reduce(LambdaUtilities.addIntegerBinaryOperator());
-        double avg = (double) total.get().intValue() / col.size();
-        Stream<Integer> streamStanDeviation = streamFor(col);
-        BigDecimal deviationSquare = streamStanDeviation.reduce(new BigDecimal(0.0),
-                LambdaUtilities.deviationSequareFunction(avg),
-                LambdaUtilities.addBigDecimalBinaryOperator());
-        double stdev = deviationSquare.doubleValue() / col.size();
-
-        int totalExpected = 0;
-        for (Integer aCol : col)
-            totalExpected +=  aCol;
-        assertEquals(totalExpected, total.get().intValue());
-        double avgExpected = (double)totalExpected / col.size();
-        assertEquals(avgExpected, avg);
-
-        BigDecimal deviationSquareExpected = new BigDecimal(0.0);
-        for (Integer aCol : col)
-            deviationSquareExpected = deviationSquareExpected
-                    .add(new BigDecimal(avg - aCol).pow(2));
-        assertEquals(deviationSquare, deviationSquareExpected);
-
-        double stddvExpected = deviationSquareExpected.doubleValue() / col.size();
-        assertEquals(stddvExpected, stdev);
-    }
-
-    @Override
-    protected Collection<Integer> generate(int size) {
-        Collection<Integer> col = createEmptyCollection();
-        IntStream.range(0, size).forEach(i -> col.add(i));
-        return col;
-    }
-    
-    @Override
-    protected Object[] predicateAndDesc(int size){
-            boolean isUp = rand.nextBoolean();
-            int limit = rand.nextInt(size);
-            return new Object[]{ LambdaUtilities.randomIntegerPredicate(isUp, limit), 
-                    String.format("i -> i %s %d", isUp ? ">=" : "<", limit)};
-    }
-
-    //BinaryOperator, descrption, stateless
-    @Override
-    protected Object[][] binaryOperatorAndDesc() {
-        return new Object[][]{
-            {(BinaryOperator<Integer>)Integer::sum, "Integer::sum", false},
-            {(BinaryOperator<Integer>)Integer::max, "Integer::sum", true},
-            {(BinaryOperator<Integer>)Integer::max, "Integer::sum", true},
-        }; 
-    }
-    
-    //Function<U, ? extends Comparable>, descrption for Function<? extends Comparable>
-    @Override
-    protected Object[][] functionAndDesc(){
-        Function<Integer, String> toStr = String::valueOf;
-        return new Object[][]{
-            {(Function<Integer, Integer>)i -> i++, "i -> i++"},
-            {toStr, "String::valueOf"},
-        };
-    }
-    
-    @Override
-    protected Integer[] bases(int size){
-        return new Integer[]{-1, 0, 1, size /2, size - 1, size, size + 1};
-    }
-
-    @Override
-    protected Object[] validArrayGeneratorAndDesc() {
-        return new Object[]{
-            new IntFunction[]{(IntFunction)Integer[]::new, (IntFunction)Number[]::new},
-            "{Integer[]::new, Number[]::new}"
-        };
-    }
-
-    @Override
-    protected Object[][] invalidArrayGeneratorAndDesc() {
-        return new Object[][]{
-            {(IntFunction)Double[]::new, "Double[]::new"},
-            {(IntFunction)String[]::new, "String[]::new"},
-        };
-    }
-
-    @Override
-    protected IntFunction<Integer> createFunction() {
-        return Integer::valueOf;
-    }
-
-    @Override
-    protected ToIntFunction<Integer> intValueFunction() {
-        return Integer::intValue;
-    }
-}
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Basic test for Stream<Integer>
+ * @library /sqeutil
+ * @(#) IntegerStreamTest.java
+ * @author Tristan Yan
+ * @run testng IntegerStreamTest
+ */
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.IntSummaryStatistics;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.ToIntFunction;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+
+public class IntegerStreamTest<T extends Collection<Integer>> extends 
+        GenericStreamTest<Integer, Collection<Integer>> {
+    private static HashMap<Boolean, Map<Integer, Integer[]>> cache = new HashMap<>();
+    
+    static {
+        Function<Boolean, Function<Integer, Integer[]>> randomToArrays = random ->
+            random ? ( i -> rand.ints().limit(i).boxed().toArray(Integer[]::new)) : 
+            (i -> IntStream.rangeClosed(1, i).boxed().toArray(Integer[]::new));
+        initCache(cache, randomToArrays,  "IntegerStreamTest");
+    }
+    
+    @Factory
+    public static Object[] create(){
+        TripleFunction<Class,ParallelType,Integer, IntegerStreamTest> 
+            supplierWithInitSize = 
+            IntegerStreamTest<Collection<Integer>>::<Class,ParallelType,Integer>new;
+        BiFunction<Class,ParallelType, IntegerStreamTest> supplier =
+              IntegerStreamTest<Collection<Integer>>::<Class,ParallelType>new;
+        List tests = new ArrayList();
+        Arrays.stream(ParallelType.values()).forEach(parallelType -> {
+            Arrays.stream(defaultConstructorClazz).forEach( clazz -> 
+                tests.add(new IntegerReduceTest(supplier.apply(
+                    clazz, parallelType)))); 
+            Arrays.stream(capacityConstructorClazz).forEach( clazz ->
+                tests.add(new IntegerReduceTest(supplierWithInitSize.apply(
+                        clazz, parallelType,MEDIUM_DATA_SIZE))));
+            Arrays.stream(defaultComparableConstructorClazz).forEach(clazz -> { 
+                tests.add(new IntegerReduceTest(supplier.apply(clazz, 
+                        parallelType)));});
+            Arrays.stream(capacityComparableConstructorClazz).forEach(clazz -> { 
+                tests.add(new IntegerReduceTest(supplierWithInitSize.apply(clazz, 
+                        parallelType, MEDIUM_DATA_SIZE)));});
+        });
+        tests.addAll(Arrays.asList(GenericStreamTest.create(
+                supplierWithInitSize, supplier, true)));
+        return tests.toArray();
+    }
+
+    private IntegerStreamTest(Class clazz,
+            ParallelType parallelType, int initSize) {
+        super(clazz, parallelType, Comparator.naturalOrder(), initSize);
+    }
+
+   private IntegerStreamTest(Class clazz,
+            ParallelType parallelType) {
+        super(clazz, parallelType, Comparator.naturalOrder());
+    }
+
+    @Override
+    public String getTestName() {
+        return typeObject.getName() + "<Integer>";
+    }
+
+    @Override
+    protected Integer[] getArray(int size, boolean random){   
+        return cache.get(random).get(size);  
+    }
+
+    @Override
+    protected Object[] predicateAndDesc(int size){
+        boolean isUp = rand.nextBoolean();
+        int limit = rand.nextInt(size);
+        return new Object[]{ LambdaUtilities.randomIntegerPredicate(isUp, limit), 
+                String.format("i -> i %s %d", isUp ? ">=" : "<", limit)};
+    }
+
+    //BinaryOperator, descrption, stateless
+    @Override
+    protected Object[][] binaryOperatorAndDesc() {
+        return new Object[][]{
+            {(BinaryOperator<Integer>)Integer::sum, "Integer::sum", false},
+            {(BinaryOperator<Integer>)Integer::max, "Integer::max", true},
+            {(BinaryOperator<Integer>)Integer::min, "Integer::min", true},
+        }; 
+    }
+    
+    //Function<U, ? extends Comparable> and descrption for Function
+    @Override
+    protected Object[][] functionAndDesc(){
+        Function<Integer, String> toStr = String::valueOf;
+        return new Object[][]{
+            {(Function<Integer, Integer>)i -> i++, "i -> i++"},
+            {toStr, "String::valueOf"},
+        };
+    }
+    
+    @Override
+    protected Integer[] bases(int size){
+        return new Integer[]{-1, 0, 1, size /2, size - 1, size, size + 1};
+    }
+
+    @Override
+    protected Object[] validArrayGeneratorAndDesc() {
+        return new Object[]{
+            new IntFunction[]{
+                (IntFunction)Integer[]::new, 
+                (IntFunction)Number[]::new},
+            "{Integer[]::new, Number[]::new}"
+        };
+    }
+
+    @Override
+    protected Object[][] invalidArrayGeneratorAndDesc() {
+        return new Object[][]{
+            {(IntFunction)Double[]::new, "Double[]::new"},
+            {(IntFunction)String[]::new, "String[]::new"},
+        };
+    }
+
+    @Override
+    protected IntFunction<Integer> createFunction() {
+        return Integer::valueOf;
+    }
+
+    @Override
+    protected ToIntFunction<Integer> intValueFunction() {
+        return Integer::intValue;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/LimitTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class LimitTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public LimitTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionDataWithLimit")
+    public void testLimit(String desc, Collection<U> col, int withBoundryLimit, int beyondBoundryLimit) {
+        Collection<U> resultWithBoundary = streamFor(col).limit(withBoundryLimit)
+                .collect(Collectors.<U,List<U>>toCollection(LinkedList::new));
+        assertEquals(resultWithBoundary.size(), withBoundryLimit);
+
+        Collection<U> resultBeyondBoundary = streamFor(col).limit(beyondBoundryLimit)
+                .collect(Collectors.<U,List<U>>toCollection(LinkedList::new));
+        assertEquals(col.size(), resultBeyondBoundary.size());
+
+        assertEquals(streamFor(createEmptyCollection()).limit(withBoundryLimit).count(), 0);
+        assertEquals(streamFor(createEmptyCollection()).limit(beyondBoundryLimit).count(), 0);
+    }
+    
+    @Test(dataProvider="exceptionTestData",expectedExceptions = IllegalArgumentException.class)
+    public void testLimitException(String desc, Collection<U> col){
+        streamFor(col).limit(-1).toArray();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/MatchTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import java.util.function.Predicate;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class MatchTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public MatchTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionPredicateData")
+    public void testXxxMatch(String desc, Collection<U> col, Predicate<U> predicate) {
+        assertEquals(streamFor(col).allMatch(predicate),
+                verifyMatch(col, predicate, true));
+        assertEquals(streamFor(col).anyMatch(predicate),
+                verifyMatch(col, predicate, false));
+        assertEquals(streamFor(col).noneMatch(predicate),
+                verifyMatch(col, predicate.negate(), true)); 
+
+        assertTrue(streamFor(createEmptyCollection()).allMatch(predicate));
+        assertFalse(streamFor(createEmptyCollection()).anyMatch(predicate));
+        assertTrue(streamFor(createEmptyCollection()).noneMatch(predicate));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/MaxAndMinTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class MaxAndMinTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public MaxAndMinTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    TripleFunction<Collection<U>,Comparator<U>,Boolean,U> maxMinFunctions[] = new TripleFunction[] {
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert(!col.isEmpty());
+                Iterator<U> it = col.iterator();
+                U choosen = it.next();
+                while(it.hasNext()) {
+                    U next = it.next();
+                    if (!(c.compare(choosen, next) < 0 ^ isMax)) choosen = next;
+                }
+                return choosen;
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert(!col.isEmpty());
+                U choosen = isMax ? streamFor(col).collect(Collectors.<U>maxBy(c)).get() :
+                        streamFor(col).collect(Collectors.<U>minBy(c)).get();
+                return choosen;
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert (!col.isEmpty());
+                Optional<U> choosen = col.stream().reduce(isMax ? 
+                        LambdaUtilities.maxGenericBinaryOperator(c) :
+                        LambdaUtilities.minGenericBinaryOperator(c) );
+                assert(choosen.isPresent());
+                return choosen.get();
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert (!col.isEmpty());
+                U any = col.iterator().next();
+                U choosen = col.stream().reduce(any, 
+                        isMax ? LambdaUtilities.maxGenericFunction(c) : LambdaUtilities.minGenericFunction(c),
+                        isMax ? LambdaUtilities.maxGenericBinaryOperator(c) : LambdaUtilities.minGenericBinaryOperator(c));
+                return choosen;
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert (!col.isEmpty());
+                U choosen = col.stream().collect(Collectors.<U>reducing(isMax ? 
+                        LambdaUtilities.maxGenericBinaryOperator(c) :
+                        LambdaUtilities.minGenericBinaryOperator(c))).get();
+                return choosen;
+             }),
+    };
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testMaxAndMin(String desc, Collection<U> col, Function<U, ? extends Comparable> mapFunc) {
+        Comparator<U> comp = Comparator.comparing(mapFunc);
+        Arrays.asList(true, false).stream().peek((testMax) -> {
+            Optional<U> optional = testMax ? streamFor(col).max(comp) : streamFor(col).min(comp);
+            assertTrue(optional.isPresent());
+            for(BaseStreamTest.TripleFunction<Collection<U>,Comparator<U>,Boolean,U> func : maxMinFunctions) {
+                assertEquals(comp.compare(optional.get(), func.apply(col, comp, testMax)), 0);
+            }
+        }).forEach((testMax) -> {
+            if(testMax)
+                assertFalse(streamFor(createEmptyCollection()).max(comp).isPresent());
+            else
+                assertFalse(streamFor(createEmptyCollection()).min(comp).isPresent());
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/OperatorTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.DataProvider;
+
+public class OperatorTest<U, V extends Collection<U>> extends BaseStreamTest {
+    protected final GenericStreamTest<U, V> test;
+ 
+    public OperatorTest(GenericStreamTest<U, V> test) {
+        super(test.parallelType);
+        this.test = test;
+    }
+    
+    protected Stream<U> streamFor(Collection<U> c1) {
+        return (test.getParallelType() == BaseStreamTest.ParallelType.Parallel) ? 
+                c1.parallelStream(): (test.getParallelType() == BaseStreamTest.ParallelType.Sequential)
+                ? c1.parallelStream().sequential() : c1.stream();
+    }
+
+    @DataProvider
+    protected Iterator<Object[]> collectionArrayGeneratorData(){
+        return test.collectionArrayGeneratorData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionArrayInvalidGeneratorData(){
+        return test.collectionArrayInvalidGeneratorData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionBinaryOpeatorData(){
+        return test.collectionBinaryOpeatorData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionData() {
+        return test.collectionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionDataWithLimit() {
+        return test.collectionDataWithLimit();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionDataWithSelection() {
+        return test.collectionDataWithSelection();
+    }
+    @DataProvider
+    public Iterator<Object[]> collectionDualPredicateData() {
+         return test.collectionDualPredicateData();
+     }
+    @DataProvider
+    protected Iterator<Object[]> collectionFunctionData(){
+        return test.collectionFunctionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionKeyValueFunctionData(){
+        return test.collectionKeyValueFunctionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionPredicateData() {
+        return test.collectionPredicateData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionStartEndData() {
+        return test.collectionStartEndData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> concatCollectionData(){
+        return test.concatCollectionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]>  exceptionTestData() {
+        return test.exceptionTestData();
+    }
+        
+    protected static <T> void assertEqualContents(Collection<T> result1,
+            Collection<T> result2, Comparator<T> comparator) {
+        assertEquals(result1.size(), result2.size());
+        ArrayList<T> a = new ArrayList<>(result1);
+        ArrayList<T> b = new ArrayList<>(result2);
+        Collections.sort(a, comparator);
+        Collections.sort(b, comparator);
+
+        for(int i = 0; i < result1.size(); i++)
+            assertEquals(comparator.compare(a.get(i), b.get(i)), 0);
+    }
+
+    public Collection<U> createEmptyCollection(){
+        return test.createEmptyCollection();
+    }
+
+    protected void verifySlice(Collection<U> col, Collection<U> subL, int skip, int limit, boolean ordered) {
+        int toIndex = skip + limit < col.size() ? skip + limit : col.size();
+        if (ordered) {
+            assertEquals(new ArrayList(col).subList(skip, toIndex), subL);
+        } else {
+            // Unordered: verify that all items from the slice are
+            // present in the original collection
+            assertTrue(col.containsAll(subL));
+            assertEquals(subL.size(), toIndex - skip); 
+        }
+    }
+   
+    protected void verifyFlatMap(Collection<U> orig, Collection<U> result, Function<U, Stream<U>> mapper) {
+        Collection<U> expected = orig.stream().map(mapper::apply).reduce(Stream::concat).
+                get().collect(Collectors.<U>toList());
+        assertEqualContents(result, expected, test.getNaturalOrderComparator());
+    }
+
+    protected boolean verifyMatch(Collection<U> col, Predicate<U> predicate, boolean checkAll) {
+        for(U current : col) {
+            if (checkAll ^ predicate.test(current) )
+                    return !checkAll;
+        }
+        return checkAll;
+    }
+
+    protected void verifyAfterMap(Collection<U> origCol, Object[] result, Function<U, ? extends Object> mapFunc) {
+        int index = 0;
+        assertEquals(origCol.size(), result.length);
+        for(U element : origCol) 
+            assertEquals(mapFunc.apply(element), result[index++]);
+    }
+    static enum GenericOperatorType{
+        CONCATENATE{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ConcatTest::new;
+            }
+        },
+        COLLECT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return CollectTest::new;
+            }
+        },
+        COUNT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return CountTest::new;
+            }
+        },
+        DISTINCT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return DistinctTest::new;
+            }
+        },
+        FILTER {
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return FilterTest::new;
+            }
+        },
+        FIND{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return FindTest::new;
+            }
+        },
+        FOREACH{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ForEachTest::new;
+            }
+        },
+        FLATMAP{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return FlatMapTest::new;
+            }
+        },
+        LIMIT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return LimitTest::new;
+            }
+        },
+        MAX_MIN{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return MaxAndMinTest::new;
+            }
+        },
+        MATCH{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return MatchTest::new;
+            }
+        },
+        PEEK{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return PeekTest::new;
+            }
+        },
+        REDUCE{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ReduceTest::new;
+            }
+        },
+        SORTED{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return SortedTest::new;
+            }
+        },
+        SUBSTREAM{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return SubstreamTest::new;
+            }
+        },
+        TOARRAY{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ToArrayTest::new;
+            }
+        };
+
+        abstract Function<GenericStreamTest, ? extends OperatorTest> getConstructor();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/PeekTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class PeekTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public PeekTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testPeek(String desc, Collection<U> col, Function<U, ? extends Object> mapFunc) {
+        //Note ArrayList is not a concurrent data type, if we don't set initial
+        //size, we could get AIOOBE
+        List<U> peekList = new ArrayList<>(col.size());
+        Stream<U> peekedStream = streamFor(col).peek(peekList::add);
+        //Lasiness check for peek
+        assertTrue(peekList.isEmpty());
+        Object[] result = peekedStream.map(mapFunc).toArray();
+        verifyAfterMap(col, result, mapFunc);
+        
+        List<U> emptyList = new ArrayList<>();
+        assertEquals(streamFor(createEmptyCollection()).peek(emptyList::add).count(), 0);
+        assertTrue(emptyList.isEmpty());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ReduceTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.function.BinaryOperator;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class ReduceTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ReduceTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionBinaryOpeatorData")
+    public void testReduce(String desc, Collection<U> col, U base, 
+            BinaryOperator<U> op, boolean stateless)  {
+        Optional<U> reduceResult = streamFor(col).reduce( op);
+        assertTrue(reduceResult.isPresent());
+        Iterator<U> iter = col.iterator();
+        U expected = iter.next();
+        while(iter.hasNext())
+            expected = op.apply(expected, iter.next());
+        assertEquals(reduceResult.get(), expected);
+
+        assertEquals(streamFor(createEmptyCollection()).reduce(base,op), base);
+        assertFalse(streamFor(createEmptyCollection()).reduce(op).isPresent());
+
+        if(stateless || !streamFor(col).isParallel()) {
+            U reduceWithBaseResult = streamFor(col).reduce(base, op);
+            U expectedWithBase = base;
+            for(U aCol : col)
+                expectedWithBase = op.apply(expectedWithBase, aCol);
+            assertEquals(reduceWithBaseResult, expectedWithBase);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SortedTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class SortedTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public SortedTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testSorted(String desc, Collection<U> col, 
+            Function<U, ? extends Comparable> mapFunc) {
+        //SortedSet instance's stream can't be reordered, we use ArrayList to do
+        //reorder
+        Comparator<U> comp = Comparator.comparing(mapFunc);
+        List<U> sorted = new ArrayList<>(col);
+        List<U> reversed = streamFor(col).sorted(comp).collect(Collectors.<U>toList());
+        Collections.sort(sorted, comp);
+        assertEquals(sorted, reversed);
+
+        assertEquals(streamFor(createEmptyCollection()).sorted(comp).count(), 0);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SortedTestForCompable.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class SortedTestForCompable<U, V extends Collection<U>> 
+        extends OperatorTest<U, V>{
+    public SortedTestForCompable(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    //Note non-Comparable U need override this method
+    @Test(dataProvider="collectionData")
+    public void testSortedSpecial(String desc, Collection<U> col) {
+        // SortedSet instance's stream can't be reordered, we use ArrayList to do reorder
+        List<U> sorted = new ArrayList<>(col);
+        List<U> reversed = streamFor(col).sorted().collect(Collectors.<U>toList());
+        Collections.sort(sorted, test.getNaturalOrderComparator());
+        assertEquals(sorted, reversed);
+
+        assertEquals(streamFor(createEmptyCollection()).sorted().count(), 0);
+    } 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SortedTestForNonCompable.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import org.testng.annotations.Test;
+
+public class SortedTestForNonCompable<U, V extends Collection<U>> 
+        extends OperatorTest<U, V>{
+    public SortedTestForNonCompable(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    //StringBuilder is not Comparable
+    //Not single element stream won't throw ClassCastException
+    @Test(dataProvider="exceptionTestData", expectedExceptions = ClassCastException.class)
+    public void testSortedSpecial(String desc, Collection<U> col) {
+        streamFor(col).sorted().findFirst();
+        System.out.println(col.size());
+    }  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/StringBuilderSpecialTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class StringBuilderSpecialTest<V extends Collection<StringBuilder>> 
+    extends OperatorTest<StringBuilder, V> {
+    public StringBuilderSpecialTest(GenericStreamTest<StringBuilder, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testCollectJoining(String desc, Collection<StringBuilder> col, 
+            Function<StringBuilder, ? extends Object> mapFunc) {
+        //test joining
+        String joined = streamFor(col).collect(Collectors.joining());
+        int pos = 0;
+        for(StringBuilder sb : col) {
+            String toString = sb.toString();
+            assertEquals(joined.substring(pos, pos + toString.length()), toString);
+            pos += toString.length();
+        }
+    }
+}
--- a/test/java/util/stream/Stream/StringBuilderStreamTest.java	Tue Aug 27 12:38:34 2013 +0200
+++ b/test/java/util/stream/Stream/StringBuilderStreamTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -27,122 +27,154 @@
  * @library /sqeutil
  * @(#) StringBuilderStreamTest.java
  * @author Eric Wang/Tristan Yan
- * @run testng/othervm -mx1g StringBuilderStreamTest
+ * @run testng/othervm -mx2g StringBuilderStreamTest
  */
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
 import java.util.function.Function;
 import java.util.function.IntFunction;
 import java.util.function.Predicate;
 import java.util.function.ToIntFunction;
-import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import static org.testng.Assert.assertEquals;
 import org.testng.annotations.Factory;
-import org.testng.annotations.Test;
 
 public class StringBuilderStreamTest<T extends Collection<StringBuilder>> extends
             GenericStreamTest<StringBuilder, Collection<StringBuilder>> {
-    public StringBuilderStreamTest(Class clazz,
-            ParallelType parallelType, int initSize) {
-        super(clazz, parallelType, Comparator.comparing(StringBuilder::toString), initSize);
+    private final static HashMap<Boolean, Map<Integer, StringBuilder[]>> cache 
+            = new HashMap<>();
+    
+    private final static int MAX_STRING_LEN = 1 << 3;
+
+    static {
+        Function<String, StringBuilder> strToBuilder = StringBuilder::new;
+        BiFunction<Integer, Integer, String> lensToString 
+                = StringUtilities::randomString;
+        BiFunction<Integer, Integer, StringBuilder> lensToBuilder 
+                = lensToString.andThen(strToBuilder);
+        Function<Integer, StringBuilder> randomLenToBuilder = len ->
+             lensToBuilder.apply(MAX_STRING_LEN  + 1, 1);
+        Function<Integer, String> valueToString = String::valueOf;
+        Function<Integer, StringBuilder> valueToStringBuilder 
+                = valueToString.andThen(strToBuilder);
+        BiFunction<Boolean, Integer,StringBuilder> randomnessLenToStringBuilder 
+            = (random, len) -> {   
+                if(random) 
+                    return randomLenToBuilder.apply(len); 
+                else 
+                    return valueToStringBuilder.apply(len); 
+            };
+        Function<Boolean, Function<Integer, StringBuilder[]>> 
+                randomToBuildersFunction = random -> 
+                (size -> IntStream.rangeClosed(1, size).mapToObj(len -> 
+                        randomnessLenToStringBuilder.apply(random, len)).
+                        toArray(StringBuilder[]::new));
+        initCache(cache, randomToBuildersFunction,  "StringBuilderStreamTest");
     }
 
-    public StringBuilderStreamTest(Class clazz,
+    public StringBuilderStreamTest(Class clazz, 
+            ParallelType parallelType, int initSize) {
+        super(clazz, parallelType, Comparator.comparing((Function<StringBuilder,
+                String>)StringBuilder::toString), initSize);
+    }
+
+    public StringBuilderStreamTest(Class clazz, 
             ParallelType parallelType) {
-        super(clazz, parallelType, Comparator.comparing(StringBuilder::toString));
+        super(clazz, parallelType, Comparator.comparing((Function<StringBuilder,
+                String>)StringBuilder::toString));
     }
 
     @Factory
     public static Object[] create(){
-      TripleFunction<Class,ParallelType,Integer,StringBuilderStreamTest> supplierWithInitSize =
-              StringBuilderStreamTest<Collection<StringBuilder>>::<Class,ParallelType,Integer>new;
-      BiFunction<Class,ParallelType,StringBuilderStreamTest> supplier =
-              StringBuilderStreamTest<Collection<StringBuilder>>::<Class,ParallelType>new;
-      return GenericStreamTest.create(supplierWithInitSize, supplier, false);
+        TripleFunction<Class,ParallelType,Integer,StringBuilderStreamTest> 
+            supplierWithInitSize =
+            StringBuilderStreamTest<Collection<StringBuilder>>::<Class,ParallelType,Integer>new;
+        BiFunction<Class,ParallelType,StringBuilderStreamTest> supplier =
+            StringBuilderStreamTest<Collection<StringBuilder>>::<Class,ParallelType>new;
+        List tests = new ArrayList();
+        Arrays.stream(ParallelType.values()).forEach(parallelType -> {
+            Arrays.stream(defaultConstructorClazz).forEach( clazz -> 
+                tests.add(new StringBuilderSpecialTest(supplier.apply(
+                    clazz, parallelType)))); 
+            Arrays.stream(capacityConstructorClazz).forEach( clazz ->
+                tests.add(new StringBuilderSpecialTest(supplierWithInitSize.apply(
+                        clazz, parallelType,MEDIUM_DATA_SIZE))));
+        });
+        tests.addAll(Arrays.asList(GenericStreamTest.create(
+                supplierWithInitSize, supplier, false)));
+      return tests.toArray();
     }
 
     @Override
     public String getTestName() {
         return typeObject.getName() + "<StringBuilder>";
     }
-
-    @Test(dataProvider="collectionFunctionData")
-    public void testCollectJoining(String desc, Collection<StringBuilder> col, Function<StringBuilder, ? extends Object> mapFunc) {
-        //test joining
-        String joined = streamFor(col).collect(Collectors.joining());
-        int pos = 0;
-        for(StringBuilder sb : col) {
-            String toString = sb.toString();
-            assertEquals(joined.substring(pos, pos + toString.length()), toString);
-            pos += toString.length();
-        }
-    }
-
-    //StringBuilder is not Comparable
-    //Not single element stream won't throw ClassCastException
-    @Test(dataProvider="exceptionTestData", expectedExceptions = ClassCastException.class)
-    @Override
-    public void testSortedSpecial(String desc, Collection<StringBuilder> col) {
-            streamFor(col).sorted().findFirst();
-            System.out.println(col.size());
-    }
-
+  
     @Override
     protected Object[] predicateAndDesc(int size){
         LambdaUtilities.CharType charType = Arrays.stream(LambdaUtilities.CharType.values()).findAny().get();
         Boolean isFirst = rand.nextBoolean();
-       Predicate<StringBuilder> p =(Predicate<StringBuilder>) LambdaUtilities.randomSBPredicate(charType, isFirst);
-       String funcName = "";
+       Predicate<StringBuilder> p = (Predicate<StringBuilder>)
+               LambdaUtilities.randomSBPredicate(charType, isFirst);
+       String funcName;
         switch (charType) {
             case DIGIT: funcName = "isDigit"; break;
             case LOWERCASE: funcName = "isLowerCase"; break;
             case UPPERCASE: funcName = "isUpperCase"; break;
             default: funcName = "isLetterOrDigit"; break;
         }
-        return new Object[]{ p , String.format("sb -> Character.%s(%s)", funcName, isFirst ? "0" : "sb.toString().length() - 1")};
-
+        return new Object[]{ p , String.format("sb -> Character.%s(%s)", 
+            funcName, isFirst ? "0" : "sb.toString().length() - 1")};         
     }
 
     //BinaryOperator, descrption, stateless
     @Override
     protected Object[][] binaryOperatorAndDesc() {
         return new Object[][]{
-            {(BinaryOperator<StringBuilder>)StringBuilder::append, "StringBuilder::append", false},
-            {LambdaUtilities.maxGenericBinaryOperator(naturalOrderComparator), "(t1, t2) -> t1 < t2 ? t2 : t1", true},
-            {LambdaUtilities.minGenericBinaryOperator(naturalOrderComparator), " (t1, t2) -> t1 < t2 ? t1 : t2", true},
-        };
+//            {(BinaryOperator<StringBuilder>)StringBuilder::append, "StringBuilder::append", false},
+            {LambdaUtilities.maxGenericBinaryOperator(getNaturalOrderComparator()), 
+                "(t1, t2) -> t1 < t2 ? t2 : t1", true},
+            {LambdaUtilities.minGenericBinaryOperator(getNaturalOrderComparator()), 
+                " (t1, t2) -> t1 < t2 ? t1 : t2", true},
+        }; 
     }
 
-    //Function<U, ? extends Comparable>, descrption for Function<? extends Comparable>
+    //Function<U, ? extends Comparable>, descrption for Function
     @Override
     protected Object[][] functionAndDesc(){
         return new Object[][]{
-            {(Function<StringBuilder, String>)StringBuilder::toString, "StringBuilder::toString"},
+            {(Function<StringBuilder, String>)StringBuilder::toString, 
+                "StringBuilder::toString"},
         };
     }
-
+   
     @Override
-    protected Collection<StringBuilder> generate(int size) {
-        Collection<StringBuilder> col = createEmptyCollection();
-        IntStream.range(0, size).mapToObj(i -> new StringBuilder().append(i) ).forEach(sb -> col.add(sb));
-        return col;
+    protected StringBuilder[] getArray(int size, boolean random){   
+        return cache.get(random).get(size);  
+    }
+    
+    @Override
+    protected StringBuilder[] bases(int size){
+        return new StringBuilder[]{new StringBuilder(), 
+            new StringBuilder(rand.nextInt(size)), new StringBuilder(size)};
     }
 
-    @Override
-    protected StringBuilder[] bases(int size){
-        return new StringBuilder[]{new StringBuilder(), new StringBuilder(rand.nextInt(size)), new StringBuilder(size)};
-    }
-
-    //StringBuilder[] can be converted into StringBuilder[]::new,CharSequence[]::new, Object[]::new
+    //StringBuilder[] can be converted into StringBuilder[]::new,
+    //CharSequence[]::new, Object[]::new
     @Override
     protected Object[] validArrayGeneratorAndDesc() {
         return new Object[]{
-            new IntFunction[]{(IntFunction)StringBuilder[]::new, (IntFunction)CharSequence[]::new, (IntFunction)Object[]::new},
+            new IntFunction[]{
+                (IntFunction)StringBuilder[]::new, 
+                (IntFunction)CharSequence[]::new, 
+                (IntFunction)Object[]::new
+            },
             "{StringBuilder[]::new, CharSequence[]::new}, Object[]::new}"
         };
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SubstreamTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class SubstreamTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public SubstreamTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+  
+    @Test(dataProvider="collectionData")
+    public void testSubstream(String desc, Collection<U> col) {
+        BiFunction<Integer,Integer,Integer> bf = LambdaUtilities.randBetweenIntegerFunction();
+        int skip = new Random().nextInt(col.size());
+        int limit1 = bf.apply(0, col.size() - skip);
+        Collection<U> sliceCol = streamFor(col).substream(skip, skip + limit1).
+                collect(Collectors.<U>toList());
+        verifySlice(col, sliceCol, skip, limit1, !col.getClass().equals(HashSet.class));
+
+        int limitExceeded = bf.apply(col.size() - skip, Integer.MAX_VALUE);
+        Collection<U> sliceCol2 = streamFor(col).substream(skip, skip + limitExceeded).
+                collect(Collectors.<U>toList());
+        //We couldn't predicate unordered collection like HashSet behavior for substream, for unordered collection we
+        // only check the length and if data exists in original collection
+        verifySlice(col, sliceCol2, skip, limitExceeded, !col.getClass().equals(HashSet.class));
+
+        assertEquals(streamFor(col).substream(skip, skip).count(), 0);
+
+        //skip exceed collection size cause empty stream
+        Stream<U> stream3 = streamFor(col);
+        int skipExceeded = bf.apply(col.size(), Integer.MAX_VALUE);
+        assertEquals(stream3.substream(skipExceeded, skipExceeded + 1).count(), 0);
+
+        assertEquals(streamFor(createEmptyCollection()).substream(skip, skip + limit1).count(), 0);
+    }
+    
+    @Test(dataProvider="collectionStartEndData",expectedExceptions = IllegalArgumentException.class)
+    public void  testSubstreamException(String desc, Collection<U> col, long startInclusive, long endExclusive){
+        streamFor(col).substream(startInclusive).count(); 
+        streamFor(col).substream(startInclusive, endExclusive).count();  
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ToArrayTest.java	Thu Aug 29 00:12:11 2013 +0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.function.IntFunction;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class ToArrayTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ToArrayTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionArrayGeneratorData", threadPoolSize = 3)
+    public void testToArray(String desc, Collection<U> col, IntFunction[] generators) {
+        Object[] expectedArr = col.toArray();
+        assertEquals(streamFor(col).toArray(), expectedArr);
+        assertEquals(streamFor(createEmptyCollection()).toArray().length, 0);
+        
+         Arrays.stream(generators).forEach(generator -> {
+             assertEquals(streamFor(col).toArray(generator), expectedArr);
+             assertEquals(streamFor(createEmptyCollection()).toArray(generator).length, 0);
+         });
+    }
+    
+    @Test(dataProvider="collectionArrayInvalidGeneratorData",expectedExceptions = ArrayStoreException.class)
+    public void testToArrayException(String desc, Collection<U> col, IntFunction generator){
+        streamFor(col).toArray(generator);
+    }
+}
\ No newline at end of file