changeset 6981:b6997b2d522d

Merge
author coffeys
date Thu, 27 Mar 2014 00:19:41 +0000
parents f9451026fdf5 8755db523adc
children f68ad873ca8b
files test/lib/testlibrary/jdk/testlibrary/JdkFinder.java
diffstat 31 files changed, 2894 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/javax/swing/JComboBox.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/src/share/classes/javax/swing/JComboBox.java	Thu Mar 27 00:19:41 2014 +0000
@@ -1418,6 +1418,28 @@
     }
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
+        if (super.processKeyBinding(ks, e, condition, pressed)) {
+            return true;
+        }
+
+        if (!isEditable() || condition != WHEN_FOCUSED || getEditor() == null
+                || !Boolean.TRUE.equals(getClientProperty("JComboBox.isTableCellEditor"))) {
+            return false;
+        }
+
+        Component editorComponent = getEditor().getEditorComponent();
+        if (editorComponent instanceof JComponent) {
+            JComponent component = (JComponent) editorComponent;
+            return component.processKeyBinding(ks, e, WHEN_FOCUSED, pressed);
+        }
+        return false;
+    }
+
+    /**
      * Sets the object that translates a keyboard character into a list
      * selection. Typically, the first selection with a matching first
      * character becomes the selected item.
--- a/src/share/classes/sun/java2d/SunGraphics2D.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/src/share/classes/sun/java2d/SunGraphics2D.java	Thu Mar 27 00:19:41 2014 +0000
@@ -2388,6 +2388,8 @@
                 surfaceData = NullSurfaceData.theInstance;
             }
 
+            invalidatePipe();
+
             // this will recalculate the composite clip
             setDevClip(surfaceData.getBounds());
 
--- a/test/java/awt/FileDialog/SaveFileNameOverrideTest/SaveFileNameOverrideTest.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/test/java/awt/FileDialog/SaveFileNameOverrideTest/SaveFileNameOverrideTest.java	Thu Mar 27 00:19:41 2014 +0000
@@ -1,6 +1,29 @@
+/*
+ * Copyright (c) 2014, 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
-  @bug 6998877
+  @bug 6998877 8022531
   @summary After double-click on the folder names, FileNameOverrideTest FAILED
   @author Sergey.Bylokhov@oracle.com area=awt.filedialog
   @library ../../regtesthelpers
@@ -36,7 +59,8 @@
 
         String[] instructions = {
                 "1) Click on 'Show File Dialog' button. A file dialog will come up.",
-                "2) Double-click on '" + clickDirName + "' and click OK.",
+                "2) Double-click on '" + clickDirName + "' and click a confirmation",
+                "   button, it can be 'OK', 'Save' or any other platform-dependent name.",
                 "3) See result of the test below"
         };
 
--- a/test/java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/test/java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java	Thu Mar 27 00:19:41 2014 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -23,7 +23,7 @@
 
 /*
   @test
-  @bug       7154072
+  @bug       7154072 7161320
   @summary   Tests that key events with modifiers are not swallowed.
   @author    anton.tarasov: area=awt.focus
   @library   ../../../regtesthelpers
@@ -49,6 +49,11 @@
     static Robot r;
 
     public static void main(String[] args) {
+        if (sun.awt.OSInfo.getOSType() == sun.awt.OSInfo.OSType.WINDOWS) {
+            System.out.println("Skipped. Test not for MS Windows.");
+            return;
+        }
+
         f.add(t);
         f.pack();
         f.setVisible(true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JComboBox/8032878/bug8032878.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014, 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
+ * @bug 8032878
+ * @summary Checks that JComboBox as JTable cell editor processes key events
+ *          even where setSurrendersFocusOnKeystroke flag in JTable is false and
+ *          that it does not lose the first key press where the flag is true.
+ * @library ../../regtesthelpers
+ * @build Util
+ * @author Alexey Ivanov
+ */
+
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import javax.swing.*;
+import javax.swing.text.JTextComponent;
+
+import sun.awt.SunToolkit;
+
+public class bug8032878 implements Runnable {
+    private static final String ONE = "one";
+    private static final String TWO = "two";
+    private static final String THREE = "three";
+
+    private static final String EXPECTED = "one123";
+
+    private final Robot robot;
+
+    private JFrame frame;
+    private JComboBox cb;
+
+    private volatile boolean surrender;
+    private volatile String text;
+
+    public static void main(String[] args) throws Exception {
+        final bug8032878 test = new bug8032878();
+
+        test.test(false);
+        test.test(true);
+    }
+
+    public bug8032878() throws AWTException {
+        robot = new Robot();
+        robot.setAutoDelay(100);
+    }
+
+    private void setupUI() {
+        frame = new JFrame();
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        JTable table = new JTable(new String[][] {{ONE}, {TWO}, {THREE}},
+                                  new String[] { "#"});
+        table.setSurrendersFocusOnKeystroke(surrender);
+
+        cb = new JComboBox(new String[]{ONE, TWO, THREE});
+        cb.setEditable(true);
+        DefaultCellEditor comboEditor = new DefaultCellEditor(cb);
+        comboEditor.setClickCountToStart(1);
+        table.getColumnModel().getColumn(0).setCellEditor(comboEditor);
+        frame.add(table);
+
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    private void test(final boolean flag) throws Exception {
+        try {
+            surrender = flag;
+            SwingUtilities.invokeAndWait(this);
+
+            runTest();
+            checkResult();
+        } finally {
+            if (frame != null) {
+                frame.dispose();
+            }
+        }
+    }
+
+    private void runTest() throws Exception {
+        realSync();
+        // Select 'one'
+        Util.hitKeys(robot, KeyEvent.VK_TAB);
+        realSync();
+        Util.hitKeys(robot, KeyEvent.VK_1);
+        Util.hitKeys(robot, KeyEvent.VK_2);
+        Util.hitKeys(robot, KeyEvent.VK_3);
+        Util.hitKeys(robot, KeyEvent.VK_ENTER);
+        realSync();
+    }
+
+    private void checkResult() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                text = ((JTextComponent) cb.getEditor().getEditorComponent()).getText();
+            }
+        });
+        if (text.equals(EXPECTED)) {
+            System.out.println("Test with surrender = " + surrender + " passed");
+        } else {
+            System.out.println("Test with surrender = " + surrender + " failed");
+            throw new RuntimeException("Expected value in JComboBox editor '" +
+                    EXPECTED + "' but found '" + text + "'.");
+        }
+    }
+
+    private static void realSync() {
+        ((SunToolkit) (Toolkit.getDefaultToolkit())).realSync();
+    }
+
+    @Override
+    public void run() {
+        setupUI();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8027359/XML11EntityScannerTest.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,184 @@
+/*
+ * 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
+ * @bug 8027359
+ * @summary test that the XML11EntityScanner refreshes cache when it loads new data
+ * @run main XML11EntityScannerTest
+ */
+
+import java.io.*;
+import java.util.regex.Pattern;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.w3c.dom.*;
+
+
+/**
+ * XML11EntityScanner functions similarly as XMLEntityScanner in handling data
+ * cache
+ */
+public class XML11EntityScannerTest {
+    static final String rawXML =
+            "<?xml version=\"1.1\" encoding=\"UTF-8\" standalone=\"no\"?>"
+            + "<WebOfTrustRC2 Version=\"4004\">"
+            + "<Identity Name=\"maggot\" PublishesTrustList=\"true\" Version=\"1\">"
+            + "<Context Name=\"Introduction\"/>"
+            + "<Context Name=\"FreetalkRC2\"/>"
+            + "<Property Name=\"IntroductionPuzzleCount\" Value=\"10\"/>"
+            + "<TrustList>"
+            + "<Trust Comment=\"\" Identity=\"USK@fdZ2In5mnLVG6RTc5hq9P~M1EG0WuH-itZ7mnQx2iuM,aUG-57VqxQLhQ4N1uNmH9kSI2syEfVFrVOIPAKTY2Yg,AQACAAE/WebOfTrustRC2/5\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@YwwRkHSo-xU8CvSFcLqlU2FFsQ3ztjr0X~xPXkX-klY,poB3tdcXrBU9naI0pyNVYp~zQmHaFkRRTj8xB8tuiPc,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@lsd~~79wrGvfb99FnAEY4VhJg2b5KFUloCOUff-Q2fk,71eV-F580euOtaCgim69Yw~2Rjh43DT49sl6zNamjk0,AQACAAE/WebOfTrustRC2/47\" Value=\"100\"/>"
+            + "<Trust Comment=\"Automatically assigned trust to a seed identity.\" Identity=\"USK@xyzElfFQnwBb4ZuSEh1aSNsbRjEGCTa-2rcjeW58A4E,TiYrXSCcoGETPf0TWLNthaimJEP1PW7nJ2tYXKxdC4s,AQACAAE/WebOfTrustRC2/456\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@pTtYoCsMO-~~2Grqya6Y7cf7nIU3VlL4168-c6EIwA8,QabBgrH1LYKKyBROnWz1r6iI8N7WFTt-mKD-0Qxsw1w,AQACAAE/WebOfTrustRC2/133\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@m~lDSvnetPNy77wsoxDZDUf7OkgX6ZAd7ob9orm3J4Y,SEX20g148KGJg3bsxvXNPNbUsVs1yQ5LfVUOGMh~1Q0,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@ss5yQit~bQL5easM68d4sImnPAxHNUbi99XtDMhpzgQ,CnpuD8dO29KvpkQyxtz1llAxHCB7yXfqrQLNRIELZow,AQACAAE/WebOfTrustRC2/2\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@krPcyGts~~wZTbABTAJ59nSplmum2~EkSD5IzinrFko,7YEbm-YEx1LFoZVHtGmIa5q0KbEjw48Rgwx2NqwrH~o,AQACAAE/WebOfTrustRC2/15\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@Usl-yNWc3VtuQWQ9srowZaWyfB6MiD9fzM5WexrlKE8,qMS83aGFsN~aFGajUmGrnbXvRIYZMd8N8IjnGmEvi-s,AQACAAE/WebOfTrustRC2/68\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@St0yKRdQJ3Lq17yoVt9h08bMfhqRhH1vtrcVVInoZVU,BaYM72qM3CYO1yzfVyO1UDUobL56CMbt9EQt3sEXabA,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@P8v4ZHUBPYGylYC-KHeWmeu5ZvB6RPYGgKcI5639Wz8,OM9PvjwMlt4L6jKRhqpvyblwpVMYumUgYFrAu3NxY~o,AQACAAE/WebOfTrustRC2/54\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@u2vn3Lh6Kte2-TgBSNKorbsKkuAt34ckoLmgx0ndXO0,4~q8q~3wIHjX9DT0yCNfQmr9oxmYrDZoQVLOdNg~yk0,AQACAAE/WebOfTrustRC2/2\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@MotrIucaZk37pJNS~HHpW5Vea3q0EZpfENPNGSjWh9s,RkFyDjl6-l7V-xYMWtGypmDYk-VehAU1LXmNYdIlHJs,AQACAAE/WebOfTrustRC2/108\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@KXAWN8DJxJ48XzZu7IBBpZ7SFc4n-OXqu4HhQC0V9Ww,DyklyACbgDCZyFpq-LeNqmuve7KWv-WDvJicd37ycn4,AQACAAE/WebOfTrustRC2/11\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@D6BZ1sSEmDMKNMPUN9I~7AalkkXockAdtbxONEN315w,0LiGUSSv4Ln4O7Xe4GQjpMEflNN7okKAH42Vlpv8d8s,AQACAAE/WebOfTrustRC2/56\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@sDehmSJoiaKYT455GIGHIVNKMs7KmiiwXXcCIcDhZ3o,upypWy-ze9Cz7WiCnbbJmoZOh7Xtveitftc5bE~p0Ug,AQACAAE/WebOfTrustRC2/6\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@GsTGXzIm9BTM5~KSZJknfTcPpJtlRs62aJtkNp05T5A,wuQcDjsdPQD9Fa21zWGB5GiiDlmf56vI9Niu5jl8eiM,AQACAAE/WebOfTrustRC2/31\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@eLFdT9VWP60iPNf8a3AkZrzgkcgje2n3Ca1yS8Tc5HU,5D0PISp19VkgzD4VSrRFTmo2CCvRoIuxlQzgMZBmj74,AQACAAE/WebOfTrustRC2/62\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@rz12UCXn-lG53i-6JswD98Kk9Zp0kt05gqIMNYc~9d0,42hoYZ5f~1fPuyvTOVYGJ~28MgYBSfoyzceR8-u1Z2I,AQACAAE/WebOfTrustRC2/126\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@5CYp3t28N5ZbPss9XhOkwUjD~T65q6-nc4aGwbV~-O0,CBfwMjYBiqKunzj3k6Ofpo9pyQsVFPz0OUWVzfd5a0c,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@dSSrRL9BY7JmTQD0dCpcIgVaLFF7pqU8EJzVUp1BYPA,EkTPkLrhEBQLPq-dRVPB1f2CAVdFGbXbUBlIww6re60,AQACAAE/WebOfTrustRC2/5\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@cw2rrCAcYTBjlO-I8DfEj-txttebZMG2LwuPGJV3Qlg,5ZcXLJW8G-R2SFqg4TEQX7IMs~e3Q4DjxUXGuHr9fxA,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@7zpRmhkkd5XcAUY6yUwp-53t7to3UN96w98~KQEwha0,30VpXev32s2mhmM5aBRJ---I0OlYbbN6~18j8rJ6qMU,AQACAAE/WebOfTrustRC2/8\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@YmCWYwlaSeE8o~8GawGYWeuPwsgVQtlBwlBkhGQFX04,H3DthY0MZXTe4rL0vsUOOMQDaj6UB9wK59yEwG8Q6No,AQACAAE/WebOfTrustRC2/13\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@aO9svsQEWmib~UyF1ihRUHA8i6uZprGy-tIS-Od9MMk,kwaMemPMVp-jcIRgGLAdF6PZimNE2cZFbvM6ShXAuZw,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@6J7FWPHwiCElTRXAO77tMGYAiLxerNF~5olAG0alQxQ,cz72iTz9FT~H57TgroVFv1eZlN5Ia5dhCtRa8bLh1KQ,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@kukYpNG56TNUnQzQe1RZvSYoqQ5B9lcoMZyDlh7xfO4,DNybejZVcWBAaByMRYYLZlgzUjQg28V8j6Zu1CtBc~g,AQACAAE/WebOfTrustRC2/27\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@a-tin0kMl1I~8xn5lkQDqYZRExKLzJITrxcNsr4T~fY,0VmnI67gAzIpdXlZFq~hYD8ikR5IEAg5QTwQv5Ifv5M,AQACAAE/WebOfTrustRC2/24\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@g~4XXw0hjp9TLocYZzunYWX6Don2AQhG-zplmzoCmY0,lyNjClSjRCrBZXVcmPKEAfvH01ySPgv1NWqL8wd11L8,AQACAAE/WebOfTrustRC2/115\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@UXgNMPe1YbVpXHOBXgMlcm9XcGY0G3gUtu43IO-YLLA,7EHSp20GHupg0rWrGPRY1g0TFJcRs-kubVtAcQRMxAc,AQACAAE/WebOfTrustRC2/69\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@lHrF2trsC9gyVeT2zpoL6IlZMz0aKlhN4xa2Ig70rmA,niASdKFC3nDfW6KMvzcv6VmRoHakE7GQAFpfz~2-v3Y,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@hp7IFNYSA97cHNAnHcreTJjQE5fF5sbsFlvbcZXaoxQ,O5h6cAcl5MvxuE2-xOkuvUP4JkT59NQNtaSmtuAS2Y8,AQACAAE/WebOfTrustRC2/16\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@QKPxALYrv6UyAGJs7tor8YlcikFzmy2msZ~42JMT~80,vx01piijkj0o3K8gzNaAOIIZ7NAtQVvPBxlRKtc4iP0,AQACAAE/WebOfTrustRC2/35\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@NmNfUNIr2WwIb9Ej1038Pk0M5gS1M0eHKvxdWqRUfTg,JUJYTsWuNQPOHK039Rczp6oPZDbfPdbO62gSaCuBXFQ,AQACAAE/WebOfTrustRC2/69\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@ONB7kRFo7mI0O3~QLRWlTbo1oB91XmGGS7KtSzz4XVI,yGiqMWRwR~i6ffAXOTBvrngHGC6nYOETUXj4L6Izj64,AQACAAE/WebOfTrustRC2/122\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@k-i0PmxoxO6Mahx8s850Rd7TEe0r4cnEohqC66aMDKw,IlTVYmQ9OSHjiu5pOLq4t-8r50SsVPNMlXn56zfpfDI,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@GtzvV-VHMGQILkpZ3O4CWBTWlhB423UUwpIlzRDgBLs,HUxBDT-Hhy6GqjBV24NRMjlK-o76YGMEgO~ZS6yighU,AQACAAE/WebOfTrustRC2/6\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@Ws0yzkcOYw6ax~kCtnzyX4MgLBHiQd5a6u9FMUmqLG4,zqNjNNGLz7HE4pdSPTovX2AwzGQWJ3-LI7YZt7aq3gg,AQACAAE/WebOfTrustRC2/30\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@6brkdrKlglWHnqMjWG6wrdLMWGPooc~7wQ7ID-PIsJk,X3RRBIdOQ5zthpkk8FjLL33LyoVVI4csJ1~g~sZ1msc,AQACAAE/WebOfTrustRC2/63\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@4DO0Yp1a3RZeAUAjeoPVu~GqpKhaX8RYqe~mwcWgjsM,klsqky963KI6uG3JqE1crihSeBbKBgkJHkIZ2xkWJ4A,AQACAAE/WebOfTrustRC2/36\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@axtoU6zHIkx3bicWK-hLNOj0br4xi0HW1qZ8H6CEv0U,SuPIncAHyYXmR9jQkTFUJd-QgGm0g9lW5ESUjzFOl~Q,AQACAAE/WebOfTrustRC2/8\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@BYsosP8TA22rSz1uA0KGbp6OVFZXhdgAlpH4R4hX9zE,o~qV5IzMR3m7ZOnnG5FPnDqpdffEpu7yOM7VEU9j6lQ,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@EilKmVin5cVL7b4FoEQ7ZoHS932O8OI880Qkd~tmzWs,8WK34lo95u~b60GLVczYU6EiRpY0LH7130~ASP9F6dU,AQACAAE/WebOfTrustRC2/75\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@xDYiCplSPLvFGC2dQjAC6eeaYVyQMtV-HmkpuKIJPgQ,CYKZcPacSNfB67IK10xlq7~bAqR-aOnZIA~yhHs2Hj0,AQACAAE/WebOfTrustRC2/71\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@DfCUA1sEJgiGzijEO0BWgeGjjHi28GGgv76H4rLujp8,1lnaOtPiXmvhpRZkBamZNF47uETNKIBgjSzElxcLhZc,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@F45FWNz9rs6TmafG~6n5Bg3Sr69YCHY9v01KTyK17lw,ikIvUS079Qw3aQknvdM8yKgr0XwjcqHgW0pWLu-1osA,AQACAAE/WebOfTrustRC2/13\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@VTDWbj9C5FUEXZBQRXmSsV1aEdOfsB9QHKzZ7-CnCh4,aDjtAVMuGPpCmw1rnCAj5myEnq9HYZeIzrfrhJO2JNw,AQACAAE/WebOfTrustRC2/52\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@dhYMUELq~HtJOweiV2JkGcoFS6hulHd9O~7a9LpGIxM,M-H3ySL8BdCctDUvwvbFNwHUyO1zghSNyotLqkKowi8,AQACAAE/WebOfTrustRC2/20\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@oRpTFVvCqp8qFWiZyCh2QhQ85eh3eP8C8G4YTFhm~rw,kyyeUPuksdt7omGFYFxoWPz3lu6e0q~G1HBx8wFztFc,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@RINL4YHPkTUGBWSoohAoO7Knzk89XSnqnQ6pUZkRY~w,OvIyTUUf4T2Tm46-em~A7zn1zBksIwe-hJP3KKdCe6s,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@sEZ-eWgUcQSj-To7lClNN6QNoKuvt0Cz3iTGKv63wQo,krEwvob7MhJ-pGvIk-RM8pVDPFSuXYTZw58oc2Lc49o,AQACAAE/WebOfTrustRC2/1\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@gNTVpdblFLSKMzUBEQM8YTfrO2fQQNIZeV7yJRTqYTQ,EKJhCmbQ5hpMU3cd-J91uneBF7CxTLPqffPs6DxoSMs,AQACAAE/WebOfTrustRC2/21\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@AV8Ubs8pbsMQ1F028a~pSJqtatznLjvhnwfSAtm1QKg,lUHPp~mgzV-pVoG9lYpceL6oOUtFRpvyQjGQdfx1GjY,AQACAAE/WebOfTrustRC2/41\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@xb3QGWdoUpeX9Fn1ZKeDwGN884c2XAMTpYLM9z4OIKo,aWNEDvjhhacFKAjiYJLaUnK1e7dQ9sCk-cnqkGZd7F8,AQACAAE/WebOfTrustRC2/9\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@MrxyFFM~n-kZ4kYvOOZodsvAA2vwp2XtAQJCrkEEU6s,tSHvx3u7uJN8ciaTqBIzt3lLmonM9mj6I7pz88MtBXc,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@-tpkd0enlFMTnjANRjzMKyfE3uyXU-WDX8VUqk3MXEg,J6h7edIdQCsiuc53qahzMzxsyNayXL~9IR0x5QoJVxk,AQACAAE/WebOfTrustRC2/15\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@gBQsXbnA9HX6wQB8x7DIEJT6e7lOxq5jGF353Po~p90,HjdyCLfG9r-zSBN6-AXwA1he9blIO2WEN9u7dMQ7H1w,AQACAAE/WebOfTrustRC2/13\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@ye~rQ4m~pu2Iu3O2TH-GOLBbSeKoQ~QR~vC6tJbKmDg,YSuI-J1nKZjGB2zmIa9Bh2Wtud~jzYBuR7OVhXYh7qM,AQACAAE/WebOfTrustRC2/99\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@HwgX8mU9A7bd2sCsM9And7fotpMGqfba9LzxZtOHHOU,10nYjjfKDH5RB3YvCCi5bpq4GPR-myd8ea7n8DRvx~c,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@qQArPJZuODDeM6C2ndbSczsFLWmLDm2SoaE-9F1hwQU,E3x6TbIvBj~6D9GrMUWSYgnNkLRg85BXXy5~mncoNEI,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@4hm9fo4IN0akORyJECttbEGZ~rPCPQ9KKAAH2AWMy8E,klvTyVp-GJznJq8Sln4W2GUfV6tVX2TI2sPCGBFU4tM,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@x7SDH5rL2-tGOaOKFFNMRrylCq94OfiZTWt4t3nwRHk,~E-kX9VqlANo4MeccvNlXDIjJ5xTWTEDNW-Qk04Ke6U,AQACAAE/WebOfTrustRC2/17\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@A9RAAKmky5yroigSupz6Bvrmc4q5FN1SXSrSXa6oRUg,s3RfurouqPnKmlGRkERao6jOJv9kcrVBBKAHqZVuQH4,AQACAAE/WebOfTrustRC2/1\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@yEstdNIW54-3~YA7QnYodpyWgPZStskrN9WXLHujUrE,j4PciAtpUHOjR2wmaaCKwiryJAi~exjETJ13UPGJLTg,AQACAAE/WebOfTrustRC2/58\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@NZSwPe8RJQOTSQ-~cAuxy97ieuX9reSft0cyD0vfbJg,99y8KOdRJmVLCWqryDzB8NdBrQGY7V9JDFtgCQBuGsU,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@Nq6iEvHP0B2VCszLCenQrfyJmkD0vas~00-9MoWgcTA,6dI2kB1z9mtjwITkhc9~V86QE5gM9CJBMjdpvRzKAoY,AQACAAE/WebOfTrustRC2/29\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@ZaNXnLCT7OQrwhp4I9V-rI1ZAV9WzegFj0HSaEJQ-Z4,i23K-dQupDenVE8O3xGv92vVanfDeyjLYWescevMbGg,AQACAAE/WebOfTrustRC2/14\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@53e9r9zEkJ0TRW~Tq8XIWjZ3WkL7Jv5Ez8LDhdwwzwM,7a0vL0OmWkHy3gC5Zs~MxB4k0QppwK4igrH6iuwls68,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@W1c~RYRC09xIHiHIucfV~Rj4J8uKAGrUeHmrH-q-U1c,niOrI75WMQ-Dtl9luIbKBmnvf6chkQEKvUvoKvSjhxI,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@G6zv74PaPcVZcf78lWp-e1TfrCSNZa1ZaPvmjm7DVzk,f4Ft3sLQ6cUEwpumpTMt5N17UORfZoXjGfmke5PJbdc,AQACAAE/WebOfTrustRC2/5\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@m5ILsPVAlcOY5D91J2iQu~PIntZb3L-B1VkONjEZs2k,592dl39JXIF1kpC4OMkw7ELOhdPrn~WXBsZln20pM7Q,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@iK69tf7gzQ53oZV60rF6ZSwwCfADMRsJeG2YmODdmJc,5czI5ZmWbWLDr2L9JdDmkt7qrr8fs55VDt3tXnrFw0E,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@bloE1LJ~qzSYUkU2nt7sB9kq060D4HTQC66pk5Q8NpA,DOOASUnp0kj6tOdhZJ-h5Tk7Ka50FSrUgsH7tCG1usU,AQACAAE/WebOfTrustRC2/58\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@0j-H~zKeP9mh6LEJUl4HSJYC-lQWstYRJeC~5E2F5~c,VbjnSixETRzKp80jYYXD-bqsTUWzxwcYmI9ZSWsBrik,AQACAAE/WebOfTrustRC2/13\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@~4ZW0eji3~hYAakiCI056soETGPf9O94GtoIpE2NGEg,GdtKsS~WeDlBS~OL1egxqZ4pr-iPXHjT2zcy8pjvEK4,AQACAAE/WebOfTrustRC2/88\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@YommlOi4fTYx9axhnl9iAi9BNHRvnM5XWjl21i0563k,5FswxS7hPf2erR8KkrBobG8R9bekaakeY1tM8DDNsjI,AQACAAE/WebOfTrustRC2/2\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@-ucM1bn8sICGRAemM8wZ~BVHgX3ZPUoutjZY64mBIcQ,Ko~kC54wZ-joCpfdc67Vds8LkAIxvTJGpMtfQSl4mAA,AQACAAE/WebOfTrustRC2/2\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@VwcZEhjtMuFcYIa8r0yksTs~FvMWB7swEz6tK67Vmsw,0blSLTQDms-WWbw1IBuKIoR2ZvSHpI21lMFeByQPuII,AQACAAE/WebOfTrustRC2/56\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@HAoXk-dW6~j5eLdAZCEjyKTVC974wkdl-4QqrPcbyzE,NlS05DkGK8QzL~EVUOfb~Jl1EZoVJTQBQBzA6N2qMn4,AQACAAE/WebOfTrustRC2/7\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@2PK-12eJFcVziT6eMpiUpOpTlmDNAoVOKZvA~8s7VSg,EaHdnKfKoWQDclX1mwcQeGr5jo1ijxyExYqL7Vsf-o8,AQACAAE/WebOfTrustRC2/33\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@8D3L5TDTyp5jnbT4imUWK12QC-B0iaSxFPOstMX2URg,ZtSShNkEVV8whaGQtIxiJ3FBroihw8YDyZrWvqncs0s,AQACAAE/WebOfTrustRC2/12\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@HKv7Hp94hFz8CKlINXCImq~XIBL9VfsPSgqfR0QIZFQ,vFM45qVvCajf3iqZm~ykZYwqM0KhaUSkU3RGaxJzHLI,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@NJu4xYtC3cgZo8s2xqmap3eh1dy60tFQFoxU8aeSnq8,fp~WLcrSSUKnr9wDDz-geb8FDwADCMCA9fjKt04Cyg8,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@IazjsmIK8VnIjDkq3-ecMEKHmi0dBT1QsNBq2mp2Fuo,uu24sWwNW~tjszdw19Mz18NBGx1MSADi03BHZnttwFo,AQACAAE/WebOfTrustRC2/8\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@IfxF-y7PNV97WUiHLqlIwXQyfVsHjI-Am4unZ0AK-Qk,Xm78gNC236A3wZ1RWBnft4oBGHU1R88Yt9AlphmtJPo,AQACAAE/WebOfTrustRC2/36\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@i1YvNnlMkd0i~0SiXiDHlGaxbtYd8ZqEUij~VzxyXmM,rxi19mph9KtHA6~gVGJ1rZ6kytff~kJDm6~NrA4YQaI,AQACAAE/WebOfTrustRC2/9\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@nXf5sbMSDqE~OkCQ~8JaMgPbj2LQJcuouvO56ADo28s,uEMqVaBzpA06TaC8A0cqKuv~lSfqZBiijasA3nlQ0Fc,AQACAAE/WebOfTrustRC2/8\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@Y8fLVylNs~pB6sdA5Dl1l6T~hXQrLNZLMgfDl5-E5Z0,n0zdN5XUa-D5Puf0L9wu~xQQmU~A5TpfqJ4RFHJLjLs,AQACAAE/WebOfTrustRC2/1\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@F0ixRao2hQlvTQDkN6rPcwLTG2nA6x0r8RrTQ0443IQ,LxN-gYvq4eWRuhjAgejmgNqYJdIw0q8IJ2XNwwVHhmQ,AQACAAE/WebOfTrustRC2/12\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@Pgk~nJzSVNAjFHh-qTovvm6muY08igdOCEWuyUrbFvk,NlwUDwfQlbXRjIaFAVljD5E1loXi31Xq6dG8YC7JOR0,AQACAAE/WebOfTrustRC2/5\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@m9gYemmVNXe32Ao6jeUgW8ttgGlMSIAW1608YZ19olE,LnEWPRzsPlPfq2~gIYQ5SVV-V2lthAx254dht9EZgyU,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@Pwiulr-xlPJelS5CO4~do78zZHTL5TNIChF5hpz8nkY,z77V~KhcKZRWLSWtVzaWO-dt~TzCCJFCHUDhHXI715M,AQACAAE/WebOfTrustRC2/8\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@OH3ZkrLAkMJbQTjVW3e9ioH04F7jpUVNMekiQAAvRjs,J6qOC05GoqRgST93M1V90HWxq9VK4PCKIpltkL8GAhg,AQACAAE/WebOfTrustRC2/5\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@nirNdzBgVyqMpnuT5UrmX~TU354qDIY7XAp04Kutysg,vpf1npG3nUARPSkFRx9xbVT~w1ELw0jQhdiXbxWcafg,AQACAAE/WebOfTrustRC2/1\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@ozK579KUDjjxkve1gKeV8IDd5qe0NPtxlFVV2-8iXrM,hlU82qnHi5ZnIfSD5~hr4wmUjNFJjQYted7FJWBj8z8,AQACAAE/WebOfTrustRC2/12\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@D6JSlrnlDDXfnGhijswHC5a4-EBuYNFhg2IyoFhzRRM,tCJy6EvZRhk-Og9CIkR3jfLD4VYxwOY5Wf991XMLdmE,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@Bn1Ozb4~Q639N~GvSXrbzZoVx9ziFfbkiKf1akXr9dQ,DrwwRjH~WrErR595BqxyDeisgcTLRZjCsQUBQSdnPLk,AQACAAE/WebOfTrustRC2/10\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@~aHztTNobVhKiaJ2eE-k6LLMy3qrRzL0zvk1UZp1xAU,xs3tuQsYRrTgxoU5qrayiwoOYEOLE6bTHvIKBQLIwco,AQACAAE/WebOfTrustRC2/3\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@jr3FrHPhtxP-IYQ-A12A3jjNNK4-KcHsUH8qNpBGHJ0,WK9IlZuG17JZ3YvaRUR-3uHf1YqkxxyGxkpkLW56ZTY,AQACAAE/WebOfTrustRC2/1\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@iBBjdbuuabx3v7iy-Pt3WZjWuixqo2-rzH~2kV4FkwE,Hll6SNQ~FXY5mrOY2W0GTfyNhJSlOrYutJmoXeSKseE,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@TKOVixP3xx6nA3-cgl2fksatQzxg4LlReoK0GFl7uAo,r~MCdO2rhGxBgRYv2EPuIE-tP7-0z6vuwbS04oyoAyI,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@bK9LQT2mqilUY4DxwmlKvKi5Jfwf4Brr~EQGa8RLIRU,Ni90~c4q-VNFrxFS7cDimQwCcRsqdScHoElWQgBpoT8,AQACAAE/WebOfTrustRC2/6\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@DYXv~V1jDo0XBhaiaGeRvy-~snqMbBiFR~R8TK8VBNg,4YYHZfVVYZmudSCOetDlNxnvbLy6IULV1SOgeC1zXmI,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@CSWvDlm9RM31O9NPpZomFvpTVM8cV0brixDXxpwnJ7A,4wfD~qxb5hFgCBN0JWgK6p11wUCpOHGOWhJ4i2FgFhY,AQACAAE/WebOfTrustRC2/0\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@sFsqYnIVQ9FwULsp3e-q0M46fRw2jVsLJYF9PUyHVME,aDhfrzYPt4O0BTuuRF3aCPTR0A~zr2rqHtPpJXeSqFU,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "<Trust Comment=\"\" Identity=\"USK@1QwMtp0oc4jIh6DFUjec~U0O3ldWHrRmhh5OZd41MMo,GZ-QOMc4mAkHhG4LwJWU~-rl0zJIp90YcB5hn3M9tlg,AQACAAE/WebOfTrustRC2/4\" Value=\"100\"/>"
+            + "</TrustList>"
+            + "</Identity>"
+            + "</WebOfTrustRC2>";
+
+    /**
+     * main method.
+     *
+     * @param args Standard args.
+     */
+    public static void main(String[] args) {
+        try {
+            final Document xmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(rawXML.getBytes("UTF-8")));
+            final Element identityElement = (Element) xmlDoc.getElementsByTagName("Identity").item(0);
+            final Element trustListElement = (Element) identityElement.getElementsByTagName("TrustList").item(0);
+            final NodeList trustList = trustListElement.getElementsByTagName("Trust");
+            final Pattern keyPattern = Pattern.compile("USK@[%,~" + "*-_./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" + "]+");
+            for (int i = 0; i < trustList.getLength(); ++i) {
+                Element trustElement = (Element) trustList.item(i);
+                final String identity = trustElement.getAttribute("Identity");
+                if (!keyPattern.matcher(identity).matches()) {
+                    throw new RuntimeException("Parsing failure: Instead of USK URI I got: " + identity);
+                }
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException(ex.getMessage());
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8032909/XSLT.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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
+ * @bug 8032909
+ * @summary Test for XSLT string-length function with complementary chars
+ * @compile XSLT.java
+ * @run main/othervm XSLT a_utf16.xml a_utf16.xsl 1270
+ * @run main/othervm XSLT a_utf8.xml a_utf8.xsl 130
+ * @run main/othervm XSLT a_windows1252.xml a_windows1252.xsl 200
+ */
+
+import java.io.ByteArrayOutputStream;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+
+public class XSLT {
+    public static void main(String[] args) throws Exception {
+
+        ByteArrayOutputStream resStream = new ByteArrayOutputStream();
+        TransformerFactory trf = TransformerFactory.newInstance();
+        Transformer tr = trf.newTransformer(new StreamSource(System.getProperty("test.src", ".")+"/"+args[1]));
+        String res, expectedRes;
+        tr.transform( new StreamSource(System.getProperty("test.src", ".")+"/"+args[0]), new StreamResult(resStream));
+        res = resStream.toString();
+        System.out.println("Transformation completed. Result:"+res);
+
+        if (!res.replaceAll("\\s","").equals(args[2]))
+            throw new RuntimeException("Incorrect transformation result. Expected:"+args[2]+" Observed:"+res);
+    }
+}
Binary file test/javax/xml/jaxp/parsers/8032909/a_utf16.xml has changed
Binary file test/javax/xml/jaxp/parsers/8032909/a_utf16.xsl has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8032909/a_utf8.xml	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testxml>
+<Element>UTF-8_Element</Element>
+<Element2></Element2>
+</testxml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8032909/a_utf8.xsl	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="text" />
+
+<xsl:template match="Element">
+<xsl:value-of select="string-length(.)"/>
+</xsl:template>
+<xsl:template match="Element2">
+<xsl:value-of select="string-length(.)"/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8032909/a_windows1252.xml	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="windows-1252"?>
+<testxml>
+<Element>Windows-1252_Element</Element>
+<Element2></Element2>
+</testxml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8032909/a_windows1252.xsl	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="windows-1252"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="text" />
+
+<xsl:template match="Element">
+<xsl:value-of select="string-length(.)"/>
+</xsl:template>
+<xsl:template match="Element2">
+<xsl:value-of select="string-length(.)"/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/AssertsTest.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,237 @@
+/*
+ * 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 static jdk.testlibrary.Asserts.*;
+
+/* @test
+ * @summary Tests the different assertions in the Assert class
+ * @library /testlibrary
+ */
+public class AssertsTest {
+    private static class Foo implements Comparable<Foo> {
+        final int id;
+        public Foo(int id) {
+            this.id = id;
+        }
+
+        public int compareTo(Foo f) {
+            return new Integer(id).compareTo(new Integer(f.id));
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        testLessThan();
+        testLessThanOrEqual();
+        testEquals();
+        testGreaterThanOrEqual();
+        testGreaterThan();
+        testNotEquals();
+        testNull();
+        testNotNull();
+        testTrue();
+        testFalse();
+    }
+
+    private static void testLessThan() throws Exception {
+        expectPass(Assertion.LT, 1, 2);
+
+        expectFail(Assertion.LT, 2, 2);
+        expectFail(Assertion.LT, 2, 1);
+        expectFail(Assertion.LT, null, 2);
+        expectFail(Assertion.LT, 2, null);
+    }
+
+    private static void testLessThanOrEqual() throws Exception {
+        expectPass(Assertion.LTE, 1, 2);
+        expectPass(Assertion.LTE, 2, 2);
+
+        expectFail(Assertion.LTE, 3, 2);
+        expectFail(Assertion.LTE, null, 2);
+        expectFail(Assertion.LTE, 2, null);
+    }
+
+    private static void testEquals() throws Exception {
+        expectPass(Assertion.EQ, 1, 1);
+        expectPass(Assertion.EQ, null, null);
+
+        Foo f1 = new Foo(1);
+        expectPass(Assertion.EQ, f1, f1);
+
+        Foo f2 = new Foo(1);
+        expectFail(Assertion.EQ, f1, f2);
+        expectFail(Assertion.LTE, null, 2);
+        expectFail(Assertion.LTE, 2, null);
+    }
+
+    private static void testGreaterThanOrEqual() throws Exception {
+        expectPass(Assertion.GTE, 1, 1);
+        expectPass(Assertion.GTE, 2, 1);
+
+        expectFail(Assertion.GTE, 1, 2);
+        expectFail(Assertion.GTE, null, 2);
+        expectFail(Assertion.GTE, 2, null);
+    }
+
+    private static void testGreaterThan() throws Exception {
+        expectPass(Assertion.GT, 2, 1);
+
+        expectFail(Assertion.GT, 1, 1);
+        expectFail(Assertion.GT, 1, 2);
+        expectFail(Assertion.GT, null, 2);
+        expectFail(Assertion.GT, 2, null);
+    }
+
+    private static void testNotEquals() throws Exception {
+        expectPass(Assertion.NE, null, 1);
+        expectPass(Assertion.NE, 1, null);
+
+        Foo f1 = new Foo(1);
+        Foo f2 = new Foo(1);
+        expectPass(Assertion.NE, f1, f2);
+
+        expectFail(Assertion.NE, null, null);
+        expectFail(Assertion.NE, f1, f1);
+        expectFail(Assertion.NE, 1, 1);
+    }
+
+    private static void testNull() throws Exception {
+        expectPass(Assertion.NULL, null);
+
+        expectFail(Assertion.NULL, 1);
+    }
+
+    private static void testNotNull() throws Exception {
+        expectPass(Assertion.NOTNULL, 1);
+
+        expectFail(Assertion.NOTNULL, null);
+    }
+
+    private static void testTrue() throws Exception {
+        expectPass(Assertion.TRUE, true);
+
+        expectFail(Assertion.TRUE, false);
+    }
+
+    private static void testFalse() throws Exception {
+        expectPass(Assertion.FALSE, false);
+
+        expectFail(Assertion.FALSE, true);
+    }
+
+    private static <T extends Comparable<T>> void expectPass(Assertion assertion, T ... args)
+        throws Exception {
+        Assertion.run(assertion, args);
+    }
+
+    private static <T extends Comparable<T>> void expectFail(Assertion assertion, T ... args)
+        throws Exception {
+        try {
+            Assertion.run(assertion, args);
+        } catch (RuntimeException e) {
+            return;
+        }
+        throw new Exception("Expected " + Assertion.format(assertion, (Object[]) args) +
+                            " to throw a RuntimeException");
+    }
+
+}
+
+enum Assertion {
+    LT, LTE, EQ, GTE, GT, NE, NULL, NOTNULL, FALSE, TRUE;
+
+    public static <T extends Comparable<T>> void run(Assertion assertion, T ... args) {
+        String msg = "Expected " + format(assertion, args) + " to pass";
+        switch (assertion) {
+            case LT:
+                assertLessThan(args[0], args[1], msg);
+                break;
+            case LTE:
+                assertLessThanOrEqual(args[0], args[1], msg);
+                break;
+            case EQ:
+                assertEquals(args[0], args[1], msg);
+                break;
+            case GTE:
+                assertGreaterThanOrEqual(args[0], args[1], msg);
+                break;
+            case GT:
+                assertGreaterThan(args[0], args[1], msg);
+                break;
+            case NE:
+                assertNotEquals(args[0], args[1], msg);
+                break;
+            case NULL:
+                assertNull(args == null ? args : args[0], msg);
+                break;
+            case NOTNULL:
+                assertNotNull(args == null ? args : args[0], msg);
+                break;
+            case FALSE:
+                assertFalse((Boolean) args[0], msg);
+                break;
+            case TRUE:
+                assertTrue((Boolean) args[0], msg);
+                break;
+            default:
+                // do nothing
+        }
+    }
+
+    public static String format(Assertion assertion, Object ... args) {
+        switch (assertion) {
+            case LT:
+                return asString("assertLessThan", args);
+            case LTE:
+                return asString("assertLessThanOrEqual", args);
+            case EQ:
+                return asString("assertEquals", args);
+            case GTE:
+                return asString("assertGreaterThanOrEquals", args);
+            case GT:
+                return asString("assertGreaterThan", args);
+            case NE:
+                return asString("assertNotEquals", args);
+            case NULL:
+                return asString("assertNull", args);
+            case NOTNULL:
+                return asString("assertNotNull", args);
+            case FALSE:
+                return asString("assertFalse", args);
+            case TRUE:
+                return asString("assertTrue", args);
+            default:
+                return "";
+        }
+    }
+
+    private static String asString(String assertion, Object ... args) {
+        if (args == null) {
+            return String.format("%s(null)", assertion);
+        }
+        if (args.length == 1) {
+            return String.format("%s(%s)", assertion, args[0]);
+        } else {
+            return String.format("%s(%s, %s)", assertion, args[0], args[1]);
+        }
+    }
+}
--- a/test/lib/testlibrary/ClassFileInstaller.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/test/lib/testlibrary/ClassFileInstaller.java	Thu Mar 27 00:19:41 2014 +0000
@@ -45,7 +45,10 @@
 
             // Create the class file's package directory
             Path p = Paths.get(pathName);
-            Files.createDirectories(p.getParent());
+            Path parent = p.getParent();
+            if (parent != null) {
+                Files.createDirectories(parent);
+            }
             // Create the class file
             Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/OutputAnalyzerReportingTest.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,122 @@
+/*
+ * 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 Test the OutputAnalyzer reporting functionality,
+ *     such as printing additional diagnostic info
+ *     (exit code, stdout, stderr, command line, etc.)
+ * @library /testlibrary
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import jdk.testlibrary.OutputAnalyzer;
+
+public class OutputAnalyzerReportingTest {
+
+    public static void main(String[] args) throws Exception {
+        // Create the output analyzer under test
+        String stdout = "aaaaaa";
+        String stderr = "bbbbbb";
+        OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
+
+        // Expected summary values should be the same for all cases,
+        // since the outputAnalyzer object is the same
+        String expectedExitValue = "-1";
+        String expectedSummary =
+                " stdout: [" + stdout + "];\n" +
+                " stderr: [" + stderr + "]\n" +
+                " exitValue = " + expectedExitValue + "\n";
+
+
+        DiagnosticSummaryTestRunner testRunner =
+                new DiagnosticSummaryTestRunner();
+
+        // should have exit value
+        testRunner.init(expectedSummary);
+        int unexpectedExitValue = 2;
+        try {
+            output.shouldHaveExitValue(unexpectedExitValue);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotContain(stdout);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldContain("unexpected-stuff");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotMatch("[a]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldMatch("[qwerty]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+    }
+
+    private static class DiagnosticSummaryTestRunner {
+        private ByteArrayOutputStream byteStream =
+                new ByteArrayOutputStream(10000);
+
+        private String expectedSummary = "";
+        private PrintStream errStream;
+
+
+        public void init(String expectedSummary) {
+            this.expectedSummary = expectedSummary;
+            byteStream.reset();
+            errStream = new PrintStream(byteStream);
+            System.setErr(errStream);
+        }
+
+        public void closeAndCheckResults() {
+            // check results
+            errStream.close();
+            String stdErrStr = byteStream.toString();
+            if (!stdErrStr.contains(expectedSummary)) {
+                throw new RuntimeException("The output does not contain "
+                    + "the diagnostic message, or the message is incorrect");
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/Asserts.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,395 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+/**
+ * Asserts that can be used for verifying assumptions in tests.
+ *
+ * An assertion will throw a {@link RuntimeException} if the assertion isn't
+ * valid.  All the asserts can be imported into a test by using a static
+ * import:
+ *
+ * <pre>
+ * {@code
+ * import static com.oracle.java.testlibrary.Asserts.*;
+ * }
+ *
+ * Always provide a message describing the assumption if the line number of the
+ * failing assertion isn't enough to understand why the assumption failed. For
+ * example, if the assertion is in a loop or in a method that is called
+ * multiple times, then the line number won't provide enough context to
+ * understand the failure.
+ * </pre>
+ */
+public class Asserts {
+
+    /**
+     * Shorthand for {@link #assertLessThan(T, T)}.
+     *
+     * @see #assertLessThan(T, T)
+     */
+    public static <T extends Comparable<T>> void assertLT(T lhs, T rhs) {
+        assertLessThan(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThan(T, T, String)}.
+     *
+     * @see #assertLessThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLT(T lhs, T rhs, String msg) {
+        assertLessThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertLessThan(T, T, String)} with a default message.
+     *
+     * @see #assertLessThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLessThan(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " < " + format(rhs);
+        assertLessThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is less than {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>>void assertLessThan(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) < 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThanOrEqual(T, T)}.
+     *
+     * @see #assertLessThanOrEqual(T, T)
+     */
+    public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs) {
+        assertLessThanOrEqual(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThanOrEqual(T, T, String)}.
+     *
+     * @see #assertLessThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs, String msg) {
+        assertLessThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertLessThanOrEqual(T, T, String)} with a default message.
+     *
+     * @see #assertLessThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " <= " + format(rhs);
+        assertLessThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is less than or equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) <= 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertEquals(T, T)}.
+     *
+     * @see #assertEquals(T, T)
+     */
+    public static void assertEQ(Object lhs, Object rhs) {
+        assertEquals(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertEquals(T, T, String)}.
+     *
+     * @see #assertEquals(T, T, String)
+     */
+    public static void assertEQ(Object lhs, Object rhs, String msg) {
+        assertEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertEquals(T, T, String)} with a default message.
+     *
+     * @see #assertEquals(T, T, String)
+     */
+    public static void assertEquals(Object lhs, Object rhs) {
+        String msg = "Expected " + format(lhs) + " to equal " + format(rhs);
+        assertEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertEquals(Object lhs, Object rhs, String msg) {
+        if (lhs == null) {
+            if (rhs != null) {
+                error(msg);
+            }
+        } else {
+            assertTrue(lhs.equals(rhs), msg);
+        }
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThanOrEqual(T, T)}.
+     *
+     * @see #assertGreaterThanOrEqual(T, T)
+     */
+    public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs) {
+        assertGreaterThanOrEqual(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThanOrEqual(T, T, String)}.
+     *
+     * @see #assertGreaterThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs, String msg) {
+        assertGreaterThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertGreaterThanOrEqual(T, T, String)} with a default message.
+     *
+     * @see #assertGreaterThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " >= " + format(rhs);
+        assertGreaterThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is greater than or equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) >= 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThan(T, T)}.
+     *
+     * @see #assertGreaterThan(T, T)
+     */
+    public static <T extends Comparable<T>> void assertGT(T lhs, T rhs) {
+        assertGreaterThan(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThan(T, T, String)}.
+     *
+     * @see #assertGreaterThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGT(T lhs, T rhs, String msg) {
+        assertGreaterThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertGreaterThan(T, T, String)} with a default message.
+     *
+     * @see #assertGreaterThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " > " + format(rhs);
+        assertGreaterThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is greater than {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) > 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertNotEquals(T, T)}.
+     *
+     * @see #assertNotEquals(T, T)
+     */
+    public static void assertNE(Object lhs, Object rhs) {
+        assertNotEquals(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertNotEquals(T, T, String)}.
+     *
+     * @see #assertNotEquals(T, T, String)
+     */
+    public static void assertNE(Object lhs, Object rhs, String msg) {
+        assertNotEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertNotEquals(T, T, String)} with a default message.
+     *
+     * @see #assertNotEquals(T, T, String)
+     */
+    public static void assertNotEquals(Object lhs, Object rhs) {
+        String msg = "Expected " + format(lhs) + " to not equal " + format(rhs);
+        assertNotEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is not equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertNotEquals(Object lhs, Object rhs, String msg) {
+        if (lhs == null) {
+            if (rhs == null) {
+                error(msg);
+            }
+        } else {
+            assertFalse(lhs.equals(rhs), msg);
+        }
+    }
+
+    /**
+     * Calls {@link #assertNull(Object, String)} with a default message.
+     *
+     * @see #assertNull(Object, String)
+     */
+    public static void assertNull(Object o) {
+        assertNull(o, "Expected " + format(o) + " to be null");
+    }
+
+    /**
+     * Asserts that {@code o} is null.
+     *
+     * @param o The reference assumed to be null.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertNull(Object o, String msg) {
+        assertEquals(o, null, msg);
+    }
+
+    /**
+     * Calls {@link #assertNotNull(Object, String)} with a default message.
+     *
+     * @see #assertNotNull(Object, String)
+     */
+    public static void assertNotNull(Object o) {
+        assertNotNull(o, "Expected non null reference");
+    }
+
+    /**
+     * Asserts that {@code o} is <i>not</i> null.
+     *
+     * @param o The reference assumed <i>not</i> to be null,
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertNotNull(Object o, String msg) {
+        assertNotEquals(o, null, msg);
+    }
+
+    /**
+     * Calls {@link #assertFalse(boolean, String)} with a default message.
+     *
+     * @see #assertFalse(boolean, String)
+     */
+    public static void assertFalse(boolean value) {
+        assertFalse(value, "Expected value to be false");
+    }
+
+    /**
+     * Asserts that {@code value} is {@code false}.
+     *
+     * @param value The value assumed to be false.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertFalse(boolean value, String msg) {
+        assertTrue(!value, msg);
+    }
+
+    /**
+     * Calls {@link #assertTrue(boolean, String)} with a default message.
+     *
+     * @see #assertTrue(boolean, String)
+     */
+    public static void assertTrue(boolean value) {
+        assertTrue(value, "Expected value to be true");
+    }
+
+    /**
+     * Asserts that {@code value} is {@code true}.
+     *
+     * @param value The value assumed to be true.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertTrue(boolean value, String msg) {
+        if (!value) {
+            error(msg);
+        }
+    }
+
+    private static <T extends Comparable<T>> int compare(T lhs, T rhs, String msg) {
+        assertNotNull(lhs, msg);
+        assertNotNull(rhs, msg);
+        return lhs.compareTo(rhs);
+    }
+
+    private static String format(Object o) {
+        return o == null? "null" : o.toString();
+    }
+
+    private static void error(String msg) {
+        throw new RuntimeException(msg);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/InputArguments.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+
+/**
+ * This class provides access to the input arguments to the VM.
+ */
+public class InputArguments {
+    private static final List<String> args;
+
+    static {
+        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+        args = runtimeMxBean.getInputArguments();
+    }
+
+    /**
+     * Returns true if {@code arg} is an input argument to the VM.
+     *
+     * This is useful for checking boolean flags such as -XX:+UseSerialGC or
+     * -XX:-UsePerfData.
+     *
+     * @param arg The name of the argument.
+     * @return {@code true} if the given argument is an input argument,
+     *         otherwise {@code false}.
+     */
+    public static boolean contains(String arg) {
+        return args.contains(arg);
+    }
+
+    /**
+     * Returns true if {@code prefix} is the start of an input argument to the
+     * VM.
+     *
+     * This is useful for checking if flags describing a quantity, such as
+     * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity.
+     * To check if the flag -XX:MaxMetaspaceSize is set, use
+     * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}.
+     *
+     * @param prefix The start of the argument.
+     * @return {@code true} if the given argument is the start of an input
+     *         argument, otherwise {@code false}.
+     */
+    public static boolean containsPrefix(String prefix) {
+        for (String arg : args) {
+            if (arg.startsWith(prefix)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the string containing input arguments passed to the VM
+     */
+    public static String getInputArguments() {
+        StringBuilder result = new StringBuilder();
+        for (String arg : args)
+            result.append(arg).append(' ');
+
+        return result.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/JDKToolFinder.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+import java.io.FileNotFoundException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public final class JDKToolFinder {
+
+    private JDKToolFinder() {
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code test.jdk} or {@code compile.jdk} (both are set by the jtreg test suite)
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getJDKTool(String tool) {
+
+        // First try to find the executable in test.jdk
+        try {
+            return getTool(tool, "test.jdk");
+        } catch (FileNotFoundException e) {
+
+        }
+
+        // Now see if it's available in compile.jdk
+        try {
+            return getTool(tool, "compile.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("Failed to find " + tool +
+                    ", looked in test.jdk (" + System.getProperty("test.jdk") +
+                    ") and compile.jdk (" + System.getProperty("compile.jdk") + ")");
+        }
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code compile.jdk}
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getCompileJDKTool(String tool) {
+        try {
+            return getTool(tool, "compile.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code test.jdk}
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getTestJDKTool(String tool) {
+        try {
+            return getTool(tool, "test.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static String getTool(String tool, String property) throws FileNotFoundException {
+        String jdkPath = System.getProperty(property);
+
+        if (jdkPath == null) {
+            throw new RuntimeException(
+                    "System property '" + property + "' not set. This property is normally set by jtreg. "
+                    + "When running test separately, set this property using '-D" + property + "=/path/to/jdk'.");
+        }
+
+        Path toolName = Paths.get("bin", tool + (Platform.isWindows() ? ".exe" : ""));
+
+        Path jdkTool = Paths.get(jdkPath, toolName.toString());
+        if (!jdkTool.toFile().exists()) {
+            throw new FileNotFoundException("Could not find file " + jdkTool.toAbsolutePath());
+        }
+
+        return jdkTool.toAbsolutePath().toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/JDKToolLauncher.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A utility for constructing command lines for starting JDK tool processes.
+ *
+ * The JDKToolLauncher can in particular be combined with a
+ * java.lang.ProcessBuilder to easily run a JDK tool. For example, the following
+ * code run {@code jmap -heap} against a process with GC logging turned on for
+ * the {@code jmap} process:
+ *
+ * <pre>
+ * {@code
+ * JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
+ *                                       .addVMArg("-XX:+PrintGC");
+ *                                       .addVMArg("-XX:+PrintGCDetails")
+ *                                       .addToolArg("-heap")
+ *                                       .addToolArg(pid);
+ * ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
+ * Process p = pb.start();
+ * }
+ * </pre>
+ */
+public class JDKToolLauncher {
+    private final String executable;
+    private final List<String> vmArgs = new ArrayList<String>();
+    private final List<String> toolArgs = new ArrayList<String>();
+
+    private JDKToolLauncher(String tool, boolean useCompilerJDK) {
+        if (useCompilerJDK) {
+            executable = JDKToolFinder.getJDKTool(tool);
+        } else {
+            executable = JDKToolFinder.getTestJDKTool(tool);
+        }
+        vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs()));
+    }
+
+    /**
+     * Creates a new JDKToolLauncher for the specified tool. Using tools path
+     * from the compiler JDK.
+     *
+     * @param tool
+     *            The name of the tool
+     * @return A new JDKToolLauncher
+     */
+    public static JDKToolLauncher create(String tool) {
+        return new JDKToolLauncher(tool, true);
+    }
+
+    /**
+     * Creates a new JDKToolLauncher for the specified tool in the Tested JDK.
+     *
+     * @param tool
+     *            The name of the tool
+     *
+     * @return A new JDKToolLauncher
+     */
+    public static JDKToolLauncher createUsingTestJDK(String tool) {
+        return new JDKToolLauncher(tool, false);
+    }
+
+    /**
+     * Adds an argument to the JVM running the tool.
+     *
+     * The JVM arguments are passed to the underlying JVM running the tool.
+     * Arguments will automatically be prepended with "-J".
+     *
+     * Any platform specific arguments required for running the tool are
+     * automatically added.
+     *
+     *
+     * @param arg
+     *            The argument to VM running the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addVMArg(String arg) {
+        vmArgs.add(arg);
+        return this;
+    }
+
+    /**
+     * Adds an argument to the tool.
+     *
+     * @param arg
+     *            The argument to the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addToolArg(String arg) {
+        toolArgs.add(arg);
+        return this;
+    }
+
+    /**
+     * Returns the command that can be used for running the tool.
+     *
+     * @return An array whose elements are the arguments of the command.
+     */
+    public String[] getCommand() {
+        List<String> command = new ArrayList<String>();
+        command.add(executable);
+        // Add -J in front of all vmArgs
+        for (String arg : vmArgs) {
+            command.add("-J" + arg);
+        }
+        command.addAll(toolArgs);
+        return command.toArray(new String[command.size()]);
+    }
+}
--- a/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java	Thu Mar 27 00:19:41 2014 +0000
@@ -23,8 +23,11 @@
 
 package jdk.testlibrary;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 
+/**
+ * Super class for tests which need to attach jcmd to the current process.
+ */
 public class JcmdBase {
 
     private static ProcessBuilder processBuilder = new ProcessBuilder();
@@ -32,46 +35,24 @@
     /**
      * Attach jcmd to the current process
      *
-     * @param commandArgs
-     *            jcmd command line parameters, e.g. JFR.start
+     * @param toolArgs
+     *            jcmd command line parameters, e.g. VM.flags
      * @return jcmd output
      * @throws Exception
      */
-    public final static OutputAnalyzer jcmd(String... commandArgs)
+    public final static OutputAnalyzer jcmd(String... toolArgs)
             throws Exception {
-        ArrayList<String> cmd = new ArrayList<String>();
-        String cmdString = "";
-
-        // jcmd from the jdk to be tested
-        String jcmdPath = JdkFinder.getTool("jcmd", false);
-        cmd.add(jcmdPath);
-        cmdString += jcmdPath;
-
-        String pid = Integer.toString(ProcessTools.getProcessId());
-        cmd.add(pid);
-        cmdString += " " + pid;
-
-        for (int i = 0; i < commandArgs.length; i++) {
-            cmd.add(commandArgs[i]);
-            cmdString += " " + commandArgs[i];
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd");
+        launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+        for (String toolArg : toolArgs) {
+            launcher.addToolArg(toolArg);
         }
-
-        // Log command line for debugging purpose
-        System.out.println("Command line:");
-        System.out.println(cmdString);
-
-        processBuilder.command(cmd);
+        processBuilder.command(launcher.getCommand());
+        System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
         OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
-
-        // Log output for debugging purpose
-        System.out.println("Command output:");
         System.out.println(output.getOutput());
 
-        if (output.getExitValue() != 0) {
-            throw new Exception(processBuilder.command()
-                    + " resulted in exit value " + output.getExitValue()
-                    + " , expected to get 0");
-        }
+        output.shouldHaveExitValue(0);
 
         return output;
     }
--- a/test/lib/testlibrary/jdk/testlibrary/JdkFinder.java	Mon Sep 30 16:15:49 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * 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.
- */
-
-package jdk.testlibrary;
-
-import java.io.File;
-
-public final class JdkFinder {
-
-    private JdkFinder() {
-    }
-
-    private static String getExecutable(String executable, String property) {
-        String binPath = System.getProperty(property);
-        if (binPath == null) {
-            throw new RuntimeException(
-                    "System property '" + property + "' not set");
-        }
-
-        binPath += File.separatorChar + "bin" + File.separatorChar + executable;
-
-        return binPath;
-    }
-
-    /**
-     * Returns the full path to a java launcher in jdk/bin based on system
-     * property.
-     *
-     * @param stableJdk
-     *            see {@link #getTool(String, boolean)}
-     * @return Full path to a java launcher in jdk/bin.
-     */
-    public static String getJavaLauncher(boolean stableJdk) {
-        return getTool("java", stableJdk);
-    }
-
-    /**
-     * Returns the full path to an executable in jdk/bin based on system
-     * property. Depending on value of {@code stableJdk} the method will look for
-     * either 'compile.jdk' or 'test.jdk' system properties.
-     * 'test.jdk' is normally set by jtreg. When running test separately,
-     * set this property using '-Dtest.jdk=/path/to/jdk'.
-     *
-     * @param stableJdk
-     *            If {@code true} the {@code tool} will be retrieved
-     *            from the compile (stable) JDK.
-     *            If {@code false} the {@code tool} will be retrieved
-     *            from the test JDK.
-     * @return Full path to an executable in jdk/bin.
-     */
-    public static String getTool(String tool, boolean stableJdk) {
-        if (stableJdk) {
-            return getExecutable(tool, "compile.jdk");
-        } else {
-            return getExecutable(tool, "test.jdk");
-        }
-    }
-}
--- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java	Thu Mar 27 00:19:41 2014 +0000
@@ -27,6 +27,9 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+/**
+ * Utility class for verifying output and exit value from a {@code Process}.
+ */
 public final class OutputAnalyzer {
 
     private final String stdout;
@@ -85,9 +88,9 @@
     public void shouldContain(String expectedString) {
         if (!stdout.contains(expectedString)
                 && !stderr.contains(expectedString)) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + expectedString
-                    + "' missing from stdout/stderr: [" + stdout + stderr
-                    + "]\n");
+                    + "' missing from stdout/stderr \n");
         }
     }
 
@@ -101,8 +104,9 @@
      */
     public void stdoutShouldContain(String expectedString) {
         if (!stdout.contains(expectedString)) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + expectedString
-                    + "' missing from stdout: [" + stdout + "]\n");
+                    + "' missing from stdout \n");
         }
     }
 
@@ -116,8 +120,9 @@
      */
     public void stderrShouldContain(String expectedString) {
         if (!stderr.contains(expectedString)) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + expectedString
-                    + "' missing from stderr: [" + stderr + "]\n");
+                    + "' missing from stderr \n");
         }
     }
 
@@ -132,12 +137,14 @@
      */
     public void shouldNotContain(String notExpectedString) {
         if (stdout.contains(notExpectedString)) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + notExpectedString
-                    + "' found in stdout: [" + stdout + "]\n");
+                    + "' found in stdout \n");
         }
         if (stderr.contains(notExpectedString)) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + notExpectedString
-                    + "' found in stderr: [" + stderr + "]\n");
+                    + "' found in stderr \n");
         }
     }
 
@@ -152,8 +159,9 @@
      */
     public void stdoutShouldNotContain(String notExpectedString) {
         if (stdout.contains(notExpectedString)) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + notExpectedString
-                    + "' found in stdout: [" + stdout + "]\n");
+                    + "' found in stdout \n");
         }
     }
 
@@ -168,55 +176,63 @@
      */
     public void stderrShouldNotContain(String notExpectedString) {
         if (stderr.contains(notExpectedString)) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + notExpectedString
-                    + "' found in stderr: [" + stderr + "]\n");
+                    + "' found in stderr \n");
         }
     }
 
     /**
-     * Verify that the stdout and stderr contents of output buffer matches
-     * the pattern
+     * Verify that the stdout and stderr contents of output buffer matches the
+     * pattern
      *
      * @param pattern
-     * @throws RuntimeException If the pattern was not found
+     * @throws RuntimeException
+     *             If the pattern was not found
      */
     public void shouldMatch(String pattern) {
-        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
-        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(stdout);
+        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(stderr);
         if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + pattern
-                    + "' missing from stdout/stderr: [" + stdout + stderr
-                    + "]\n");
+                    + "' missing from stdout/stderr \n");
         }
     }
 
     /**
-     * Verify that the stdout contents of output buffer matches the
-     * pattern
+     * Verify that the stdout contents of output buffer matches the pattern
      *
      * @param pattern
-     * @throws RuntimeException If the pattern was not found
+     * @throws RuntimeException
+     *             If the pattern was not found
      */
     public void stdoutShouldMatch(String pattern) {
-        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                stdout);
         if (!matcher.find()) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + pattern
-                    + "' missing from stdout: [" + stdout + "]\n");
+                    + "' missing from stdout \n");
         }
     }
 
     /**
-     * Verify that the stderr contents of output buffer matches the
-     * pattern
+     * Verify that the stderr contents of output buffer matches the pattern
      *
      * @param pattern
-     * @throws RuntimeException If the pattern was not found
+     * @throws RuntimeException
+     *             If the pattern was not found
      */
     public void stderrShouldMatch(String pattern) {
-        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                stderr);
         if (!matcher.find()) {
+            reportDiagnosticSummary();
             throw new RuntimeException("'" + pattern
-                    + "' missing from stderr: [" + stderr + "]\n");
+                    + "' missing from stderr \n");
         }
     }
 
@@ -225,18 +241,22 @@
      * match the pattern
      *
      * @param pattern
-     * @throws RuntimeException If the pattern was found
+     * @throws RuntimeException
+     *             If the pattern was found
      */
     public void shouldNotMatch(String pattern) {
-        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                stdout);
         if (matcher.find()) {
-            throw new RuntimeException("'" + pattern
-                    + "' found in stdout: [" + stdout + "]\n");
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stdout: '"
+                    + matcher.group() + "' \n");
         }
         matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
         if (matcher.find()) {
-            throw new RuntimeException("'" + pattern
-                    + "' found in stderr: [" + stderr + "]\n");
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stderr: '"
+                    + matcher.group() + "' \n");
         }
     }
 
@@ -245,13 +265,15 @@
      * pattern
      *
      * @param pattern
-     * @throws RuntimeException If the pattern was found
+     * @throws RuntimeException
+     *             If the pattern was found
      */
     public void stdoutShouldNotMatch(String pattern) {
-        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                stdout);
         if (matcher.find()) {
-            throw new RuntimeException("'" + pattern
-                    + "' found in stdout: [" + stdout + "]\n");
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stdout \n");
         }
     }
 
@@ -260,18 +282,56 @@
      * pattern
      *
      * @param pattern
-     * @throws RuntimeException If the pattern was found
+     * @throws RuntimeException
+     *             If the pattern was found
      */
     public void stderrShouldNotMatch(String pattern) {
-        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                stderr);
         if (matcher.find()) {
-            throw new RuntimeException("'" + pattern
-                    + "' found in stderr: [" + stderr + "]\n");
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stderr \n");
         }
     }
 
     /**
-     * Verifiy the exit value of the process
+     * Get the captured group of the first string matching the pattern. stderr
+     * is searched before stdout.
+     *
+     * @param pattern
+     *            The multi-line pattern to match
+     * @param group
+     *            The group to capture
+     * @return The matched string or null if no match was found
+     */
+    public String firstMatch(String pattern, int group) {
+        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(stderr);
+        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(stdout);
+        if (stderrMatcher.find()) {
+            return stderrMatcher.group(group);
+        }
+        if (stdoutMatcher.find()) {
+            return stdoutMatcher.group(group);
+        }
+        return null;
+    }
+
+    /**
+     * Get the first string matching the pattern. stderr is searched before
+     * stdout.
+     *
+     * @param pattern
+     *            The multi-line pattern to match
+     * @return The matched string or null if no match was found
+     */
+    public String firstMatch(String pattern) {
+        return firstMatch(pattern, 0);
+    }
+
+    /**
+     * Verify the exit value of the process
      *
      * @param expectedExitValue
      *            Expected exit value from process
@@ -281,12 +341,25 @@
      */
     public void shouldHaveExitValue(int expectedExitValue) {
         if (getExitValue() != expectedExitValue) {
-            throw new RuntimeException("Exit value " + getExitValue()
-                    + " , expected to get " + expectedExitValue);
+            reportDiagnosticSummary();
+            throw new RuntimeException("Expected to get exit value of ["
+                    + expectedExitValue + "]\n");
         }
     }
 
     /**
+     * Report summary that will help to diagnose the problem Currently includes:
+     * - standard input produced by the process under test - standard output -
+     * exit code Note: the command line is printed by the ProcessTools
+     */
+    private void reportDiagnosticSummary() {
+        String msg = " stdout: [" + stdout + "];\n" + " stderr: [" + stderr
+                + "]\n" + " exitValue = " + getExitValue() + "\n";
+
+        System.err.println(msg);
+    }
+
+    /**
      * Get the contents of the output buffer (stdout and stderr)
      *
      * @return Content of the output buffer
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/Platform.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+public class Platform {
+    private static final String osName      = System.getProperty("os.name");
+    private static final String dataModel   = System.getProperty("sun.arch.data.model");
+    private static final String vmVersion   = System.getProperty("java.vm.version");
+    private static final String osArch      = System.getProperty("os.arch");
+
+    public static boolean is32bit() {
+        return dataModel.equals("32");
+    }
+
+    public static boolean is64bit() {
+        return dataModel.equals("64");
+    }
+
+    public static boolean isSolaris() {
+        return isOs("sunos");
+    }
+
+    public static boolean isWindows() {
+        return isOs("win");
+    }
+
+    public static boolean isOSX() {
+        return isOs("mac");
+    }
+
+    public static boolean isLinux() {
+        return isOs("linux");
+    }
+
+    private static boolean isOs(String osname) {
+        return osName.toLowerCase().startsWith(osname.toLowerCase());
+    }
+
+    public static String getOsName() {
+        return osName;
+    }
+
+    public static boolean isDebugBuild() {
+        return vmVersion.toLowerCase().contains("debug");
+    }
+
+    public static String getVMVersion() {
+        return vmVersion;
+    }
+
+    // Returns true for sparc and sparcv9.
+    public static boolean isSparc() {
+        return isArch("sparc");
+    }
+
+    public static boolean isARM() {
+        return isArch("arm");
+    }
+
+    public static boolean isPPC() {
+        return isArch("ppc");
+    }
+
+    public static boolean isX86() {
+        // On Linux it's 'i386', Windows 'x86'
+        return (isArch("i386") || isArch("x86"));
+    }
+
+    public static boolean isX64() {
+        // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
+        return (isArch("amd64") || isArch("x86_64"));
+    }
+
+    private static boolean isArch(String archname) {
+        return osArch.toLowerCase().startsWith(archname.toLowerCase());
+    }
+
+    public static String getOsArch() {
+        return osArch;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/ProcessThread.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.assertNotEquals;
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * The helper class for starting and stopping {@link Process} in a separate thread.
+ */
+public class ProcessThread extends TestThread {
+
+    /**
+     * Creates a new {@code ProcessThread} object.
+     *
+     * @param threadName The name of thread
+     * @param cmd The string array of program and its arguments to pass to {@link ProcessBuilder}
+     */
+    public ProcessThread(String threadName, String... cmd) {
+        super(new ProcessRunnable(new ProcessBuilder(cmd)), threadName);
+    }
+
+    /**
+     * Creates a new {@code ProcessThread} object.
+     *
+     * @param threadName The name of thread.
+     * @param pb The ProcessBuilder to execute.
+     */
+    public ProcessThread(String threadName, ProcessBuilder pb) {
+        super(new ProcessRunnable(pb), threadName);
+    }
+
+    /**
+     * Stops {@link Process} started by {@code ProcessRunnable}.
+     *
+     * @throws InterruptedException
+     */
+    public void stopProcess() throws InterruptedException {
+        ((ProcessRunnable) getRunnable()).stopProcess();
+    }
+
+    /**
+     * @return The process output, or null if the process has not yet completed.
+     */
+    public OutputAnalyzer getOutput() {
+        return ((ProcessRunnable) getRunnable()).getOutput();
+    }
+
+    /**
+     * {@link Runnable} interface for starting and stopping {@link Process}.
+     */
+    static class ProcessRunnable extends XRun {
+
+        private final ProcessBuilder processBuilder;
+        private final CountDownLatch latch;
+        private volatile Process process;
+        private volatile OutputAnalyzer output;
+
+        /**
+         * Creates a new {@code ProcessRunnable} object.
+         *
+         * @param pb The {@link ProcessBuilder} to run.
+         */
+        public ProcessRunnable(ProcessBuilder pb) {
+            super();
+            this.processBuilder = pb;
+            this.latch = new CountDownLatch(1);
+        }
+
+        /**
+         * Starts the process in {@code ProcessThread}.
+         * All exceptions which occurs here will be caught and stored in {@code ProcessThread}.
+         *
+         * see {@link XRun}
+         */
+        @Override
+        public void xrun() throws Throwable {
+            this.process = processBuilder.start();
+            // Release when process is started
+            latch.countDown();
+
+            // Will block...
+            try {
+                output = new OutputAnalyzer(this.process);
+            } catch (Throwable t) {
+                String name = Thread.currentThread().getName();
+                System.out.println(String.format("ProcessThread[%s] failed: %s", name, t.toString()));
+                throw t;
+            } finally {
+                String logMsg = ProcessTools.getProcessLog(processBuilder, output);
+                System.out.println(logMsg);
+            }
+        }
+
+        /**
+         * Stops the process.
+         *
+         * @throws InterruptedException
+         */
+        public void stopProcess() throws InterruptedException {
+            // Wait until process is started
+            latch.await();
+            if (this.process != null) {
+                System.out.println("ProcessThread.stopProcess() will kill process");
+                this.process.destroy();
+            }
+        }
+
+        /**
+         * Returns the OutputAnalyzer with stdout/stderr from the process.
+         * @return The process output, or null if process not completed.
+         * @throws InterruptedException
+         */
+        public OutputAnalyzer getOutput() {
+            return output;
+        }
+    }
+
+}
--- a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java	Thu Mar 27 00:19:41 2014 +0000
@@ -25,24 +25,107 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.lang.management.ManagementFactory;
 import java.lang.management.RuntimeMXBean;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 import sun.management.VMManagement;
 
 public final class ProcessTools {
+    private static final class LineForwarder extends StreamPumper.LinePump {
+        private final PrintStream ps;
+        private final String prefix;
+        LineForwarder(String prefix, PrintStream os) {
+            this.ps = os;
+            this.prefix = prefix;
+        }
+        @Override
+        protected void processLine(String line) {
+            ps.println("[" + prefix + "] " + line);
+        }
+    }
 
     private ProcessTools() {
     }
 
     /**
+     * <p>Starts a process from its builder.</p>
+     * <span>The default redirects of STDOUT and STDERR are started</span>
+     * @param name The process name
+     * @param processBuilder The process builder
+     * @return Returns the initialized process
+     * @throws IOException
+     */
+    public static Process startProcess(String name,
+                                       ProcessBuilder processBuilder)
+    throws IOException {
+        Process p = null;
+        try {
+            p = startProcess(name, processBuilder, -1, TimeUnit.NANOSECONDS);
+        } catch (InterruptedException | TimeoutException e) {
+            // can't ever happen
+        }
+        return p;
+    }
+
+    /**
+     * <p>Starts a process from its builder.</p>
+     * <span>The default redirects of STDOUT and STDERR are started</span>
+     * @param name The process name
+     * @param processBuilder The process builder
+     * @param timeout The timeout for the warmup waiting
+     * @param unit The timeout {@linkplain TimeUnit}
+     * @return Returns the initialized {@linkplain Process}
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws TimeoutException
+     */
+    public static Process startProcess(String name,
+                                       ProcessBuilder processBuilder,
+                                       long timeout,
+                                       TimeUnit unit)
+    throws IOException, InterruptedException, TimeoutException {
+        Process p = processBuilder.start();
+        StreamPumper stdout = new StreamPumper(p.getInputStream());
+        StreamPumper stderr = new StreamPumper(p.getErrorStream());
+
+        stdout.addPump(new LineForwarder(name, System.out));
+        stderr.addPump(new LineForwarder(name, System.err));
+        final Phaser phs = new Phaser(1);
+        Future<Void> stdoutTask = stdout.process();
+        Future<Void> stderrTask = stderr.process();
+
+        try {
+            if (timeout > -1) {
+                phs.awaitAdvanceInterruptibly(0, timeout, unit);
+            }
+        } catch (TimeoutException | InterruptedException e) {
+            System.err.println("Failed to start a process (thread dump follows)");
+            for(Map.Entry<Thread, StackTraceElement[]> s : Thread.getAllStackTraces().entrySet()) {
+                printStack(s.getKey(), s.getValue());
+            }
+            stdoutTask.cancel(true);
+            stderrTask.cancel(true);
+            throw e;
+        }
+
+        return p;
+    }
+
+    /**
      * Pumps stdout and stderr from running the process into a String.
      *
-     * @param processHandler
+     * @param processBuilder
      *            ProcessHandler to run.
      * @return Output from process.
      * @throws IOException
@@ -69,22 +152,19 @@
                 stdoutBuffer);
         StreamPumper errPumper = new StreamPumper(process.getErrorStream(),
                 stderrBuffer);
-        Thread outPumperThread = new Thread(outPumper);
-        Thread errPumperThread = new Thread(errPumper);
 
-        outPumperThread.setDaemon(true);
-        errPumperThread.setDaemon(true);
-
-        outPumperThread.start();
-        errPumperThread.start();
+        Future<Void> outTask = outPumper.process();
+        Future<Void> errTask = errPumper.process();
 
         try {
             process.waitFor();
-            outPumperThread.join();
-            errPumperThread.join();
+            outTask.get();
+            errTask.get();
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             return null;
+        } catch (ExecutionException e) {
+            throw new IOException(e);
         }
 
         return new OutputBuffer(stdoutBuffer.toString(),
@@ -137,15 +217,106 @@
      */
     public static ProcessBuilder createJavaProcessBuilder(String... command)
             throws Exception {
-        String javapath = JdkFinder.getJavaLauncher(false);
+        String javapath = JDKToolFinder.getJDKTool("java");
 
         ArrayList<String> args = new ArrayList<>();
         args.add(javapath);
         Collections.addAll(args, getPlatformSpecificVMArgs());
         Collections.addAll(args, command);
 
+        // Reporting
+        StringBuilder cmdLine = new StringBuilder();
+        for (String cmd : args)
+            cmdLine.append(cmd).append(' ');
+        System.out.println("Command line: [" + cmdLine.toString() + "]");
+
         return new ProcessBuilder(args.toArray(new String[args.size()]));
-
     }
 
+    private static void printStack(Thread t, StackTraceElement[] stack) {
+        System.out.println("\t" +  t +
+                           " stack: (length = " + stack.length + ")");
+        if (t != null) {
+            for (StackTraceElement stack1 : stack) {
+                System.out.println("\t" + stack1);
+            }
+            System.out.println();
+        }
+    }
+
+    /**
+     * Executes a test jvm process, waits for it to finish and returns the process output.
+     * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added.
+     * The java from the test.jdk is used to execute the command.
+     *
+     * The command line will be like:
+     * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds
+     *
+     * @param cmds User specifed arguments.
+     * @return The output from the process.
+     */
+    public static OutputAnalyzer executeTestJvm(String... cmds) throws Throwable {
+        ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(cmds));
+        return executeProcess(pb);
+    }
+
+    /**
+     * Executes a process, waits for it to finish and returns the process output.
+     * @param pb The ProcessBuilder to execute.
+     * @return The output from the process.
+     */
+    public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable {
+        OutputAnalyzer output = null;
+        try {
+            output = new OutputAnalyzer(pb.start());
+            return output;
+        } catch (Throwable t) {
+            System.out.println("executeProcess() failed: " + t);
+            throw t;
+        } finally {
+            System.out.println(getProcessLog(pb, output));
+        }
+    }
+
+    /**
+     * Executes a process, waits for it to finish and returns the process output.
+     * @param cmds The command line to execute.
+     * @return The output from the process.
+     */
+    public static OutputAnalyzer executeProcess(String... cmds) throws Throwable {
+        return executeProcess(new ProcessBuilder(cmds));
+    }
+
+    /**
+     * Used to log command line, stdout, stderr and exit code from an executed process.
+     * @param pb The executed process.
+     * @param output The output from the process.
+     */
+    public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) {
+        String stderr = output == null ? "null" : output.getStderr();
+        String stdout = output == null ? "null" : output.getStdout();
+        String exitValue = output == null ? "null": Integer.toString(output.getExitValue());
+        StringBuilder logMsg = new StringBuilder();
+        final String nl = System.getProperty("line.separator");
+        logMsg.append("--- ProcessLog ---" + nl);
+        logMsg.append("cmd: " + getCommandLine(pb) + nl);
+        logMsg.append("exitvalue: " + exitValue + nl);
+        logMsg.append("stderr: " + stderr + nl);
+        logMsg.append("stdout: " + stdout + nl);
+        return logMsg.toString();
+    }
+
+    /**
+     * @return The full command line for the ProcessBuilder.
+     */
+    public static String getCommandLine(ProcessBuilder pb) {
+        if (pb == null) {
+            return "null";
+        }
+        StringBuilder cmd = new StringBuilder();
+        for (String s : pb.command()) {
+            cmd.append(s).append(" ");
+        }
+        return cmd.toString().trim();
+    }
 }
--- a/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java	Mon Sep 30 16:15:49 2013 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java	Thu Mar 27 00:19:41 2014 +0000
@@ -23,16 +23,65 @@
 
 package jdk.testlibrary;
 
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.OutputStream;
 import java.io.InputStream;
 import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 public final class StreamPumper implements Runnable {
 
     private static final int BUF_SIZE = 256;
 
-    private final OutputStream out;
+    /**
+     * Pump will be called by the StreamPumper to process the incoming data
+     */
+    abstract public static class Pump {
+        abstract void register(StreamPumper d);
+    }
+
+    /**
+     * OutputStream -> Pump adapter
+     */
+    final public static class StreamPump extends Pump {
+        private final OutputStream out;
+        public StreamPump(OutputStream out) {
+            this.out = out;
+        }
+
+        @Override
+        void register(StreamPumper sp) {
+            sp.addOutputStream(out);
+        }
+    }
+
+    /**
+     * Used to process the incoming data line-by-line
+     */
+    abstract public static class LinePump extends Pump {
+        @Override
+        final void register(StreamPumper sp) {
+            sp.addLineProcessor(this);
+        }
+
+        abstract protected void processLine(String line);
+    }
+
     private final InputStream in;
+    private final Set<OutputStream> outStreams = new HashSet<>();
+    private final Set<LinePump> linePumps = new HashSet<>();
+
+    private final AtomicBoolean processing = new AtomicBoolean(false);
+    private final FutureTask<Void> processingTask = new FutureTask(this, null);
+
+    public StreamPumper(InputStream in) {
+        this.in = in;
+    }
 
     /**
      * Create a StreamPumper that reads from in and writes to out.
@@ -43,8 +92,8 @@
      *            The stream to write to.
      */
     public StreamPumper(InputStream in, OutputStream out) {
-        this.in = in;
-        this.out = out;
+        this(in);
+        this.addOutputStream(out);
     }
 
     /**
@@ -54,25 +103,97 @@
      */
     @Override
     public void run() {
-        int length;
-        InputStream localIn = in;
-        OutputStream localOut = out;
-        byte[] buffer = new byte[BUF_SIZE];
+        try (BufferedInputStream is = new BufferedInputStream(in)) {
+            ByteArrayOutputStream lineBos = new ByteArrayOutputStream();
+            byte[] buf = new byte[BUF_SIZE];
+            int len = 0;
+            int linelen = 0;
 
-        try {
-            while ((length = localIn.read(buffer)) > 0 && !Thread.interrupted()) {
-                localOut.write(buffer, 0, length);
+            while ((len = is.read(buf)) > 0 && !Thread.interrupted()) {
+                for(OutputStream out : outStreams) {
+                    out.write(buf, 0, len);
+                }
+                if (!linePumps.isEmpty()) {
+                    int i = 0;
+                    int lastcrlf = -1;
+                    while (i < len) {
+                        if (buf[i] == '\n' || buf[i] == '\r') {
+                            int bufLinelen = i - lastcrlf - 1;
+                            if (bufLinelen > 0) {
+                                lineBos.write(buf, lastcrlf + 1, bufLinelen);
+                            }
+                            linelen += bufLinelen;
+
+                            if (linelen > 0) {
+                                lineBos.flush();
+                                final String line = lineBos.toString();
+                                for (LinePump lp : linePumps) {
+                                    lp.processLine(line);
+                                };
+                                lineBos.reset();
+                                linelen = 0;
+                            }
+                            lastcrlf = i;
+                        }
+
+                        i++;
+                    }
+                    if (lastcrlf == -1) {
+                        lineBos.write(buf, 0, len);
+                        linelen += len;
+                    } else if (lastcrlf < len - 1) {
+                        lineBos.write(buf, lastcrlf + 1, len - lastcrlf - 1);
+                        linelen += len - lastcrlf - 1;
+                    }
+                }
             }
+
         } catch (IOException e) {
-            // Just abort if something like this happens.
             e.printStackTrace();
         } finally {
+            for(OutputStream out : outStreams) {
+                try {
+                    out.flush();
+                } catch (IOException e) {}
+            }
             try {
-                localOut.flush();
                 in.close();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
+            } catch (IOException e) {}
         }
     }
+
+    final void addOutputStream(OutputStream out) {
+        outStreams.add(out);
+    }
+
+    final void addLineProcessor(LinePump lp) {
+        linePumps.add(lp);
+    }
+
+    final public StreamPumper addPump(Pump ... pump) {
+        if (processing.get()) {
+            throw new IllegalStateException("Can not modify pumper while " +
+                                            "processing is in progress");
+        }
+        for(Pump p : pump) {
+            p.register(this);
+        }
+        return this;
+    }
+
+    final public Future<Void> process() {
+        if (!processing.compareAndSet(false, true)) {
+            throw new IllegalStateException("Can not re-run the processing");
+        }
+        Thread t = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                processingTask.run();
+            }
+        });
+        t.setDaemon(true);
+        t.start();
+
+        return processingTask;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/TestThread.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,249 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Thread which catches exceptions thrown during the execution
+ * and stores them for later analysis.
+ *
+ * <pre>
+ * {@code
+ * TestThread thread = new TestThread(new XRun() {
+ *      public void run() {
+ *      // do something
+ *      }
+ * });
+ * thread.start();
+ * // do something
+ * Throwable uncaught = thread.getUncaught();
+ * }
+ * </pre>
+ */
+public class TestThread extends Thread {
+
+    private final Runnable runnable;
+    private volatile Throwable uncaught;
+
+    /**
+     * Returns {@link Runnable} the thread has been created with.
+     *
+     * @return The object whose {@code run} method is called
+     */
+    public Runnable getRunnable() {
+        return runnable;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param target The object whose {@code run} method is called
+     * @param name The thread name
+     */
+    public TestThread(Runnable target, String name) {
+        super(target, name);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param target The object whose {@code run} method is called
+     */
+    public TestThread(Runnable target) {
+        super(target);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param group The thread group
+     * @param target The object whose {@code run} method is called
+     * @param name The thread name
+     * @param stackSize Stack size
+     */
+    public TestThread(ThreadGroup group, Runnable target, String name,
+            long stackSize) {
+        super(group, target, name, stackSize);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param group The thread group
+     * @param target The object whose {@code run} method is called
+     * @param name The thread name
+     */
+    public TestThread(ThreadGroup group, Runnable target, String name) {
+        super(group, target, name);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param group The thread group
+     * @param target The object whose {@code run} method is called
+     */
+    public TestThread(ThreadGroup group, Runnable target) {
+        super(group, target);
+        this.runnable = target;
+    }
+
+    /**
+     * The thread executor.
+     */
+    @Override
+    public void run() {
+        try {
+            super.run();
+        } catch (Throwable t) {
+            uncaught = t;
+        }
+    }
+
+    /**
+     * Returns exception caught during the execution.
+     *
+     * @return {@link Throwable}
+     */
+    public Throwable getUncaught() {
+        return uncaught;
+    }
+
+    /**
+     * Waits for {@link TestThread} to die
+     * and throws exception caught during the execution.
+     *
+     * @throws InterruptedException
+     * @throws Throwable
+     */
+    public void joinAndThrow() throws InterruptedException, Throwable {
+        join();
+        if (uncaught != null) {
+            throw uncaught;
+        }
+    }
+
+    /**
+     * Waits during {@code timeout} for {@link TestThread} to die
+     * and throws exception caught during the execution.
+     *
+     * @param timeout The time to wait in milliseconds
+     * @throws InterruptedException
+     * @throws Throwable
+     */
+    public void joinAndThrow(long timeout) throws InterruptedException,
+            Throwable {
+        join(timeout);
+        if (isAlive()) {
+            throw new TimeoutException();
+        }
+        if (uncaught != null) {
+            throw uncaught;
+        }
+    }
+
+    /**
+     * Waits for {@link TestThread} to die
+     * and returns exception caught during the execution.
+     *
+     * @return Exception caught during the execution
+     * @throws InterruptedException
+     */
+    public Throwable joinAndReturn() throws InterruptedException {
+        join();
+        if (uncaught != null) {
+            return uncaught;
+        }
+        return null;
+    }
+
+    /**
+     * Waits during {@code timeout} for {@link TestThread} to die
+     * and returns exception caught during the execution.
+     *
+     * @param timeout The time to wait in milliseconds
+     * @return Exception caught during the execution
+     * @throws InterruptedException
+     */
+    public Throwable joinAndReturn(long timeout) throws InterruptedException {
+        join(timeout);
+        if (isAlive()) {
+            return new TimeoutException();
+        }
+        if (uncaught != null) {
+            return uncaught;
+        }
+        return null;
+    }
+
+    /**
+     * Waits until {@link TestThread} is in the certain {@link State}
+     * and blocking on {@code object}.
+     *
+     * @param state The thread state
+     * @param object The object to block on
+     */
+    public void waitUntilBlockingOnObject(Thread.State state, Object object) {
+        String want = object == null ? null : object.getClass().getName() + '@'
+                + Integer.toHexString(System.identityHashCode(object));
+        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+        while (isAlive()) {
+            ThreadInfo ti = tmx.getThreadInfo(getId());
+            if (ti.getThreadState() == state
+                    && (want == null || want.equals(ti.getLockName()))) {
+                return;
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    /**
+     * Waits until {@link TestThread} is in native.
+     */
+    public void waitUntilInNative() {
+        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+        while (isAlive()) {
+            ThreadInfo ti = tmx.getThreadInfo(getId());
+            if (ti.isInNative()) {
+                return;
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/Utils.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,232 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Common library for various test helper functions.
+ */
+public final class Utils {
+
+    /**
+     * Returns the sequence used by operating system to separate lines.
+     */
+    public static final String NEW_LINE = System.getProperty("line.separator");
+
+    /**
+     * Returns the value of 'test.vm.opts'system property.
+     */
+    public static final String VM_OPTIONS = System.getProperty("test.vm.opts", "").trim();
+
+    /**
+     * Returns the value of 'test.java.opts'system property.
+     */
+    public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
+
+
+    private Utils() {
+        // Private constructor to prevent class instantiation
+    }
+
+    /**
+     * Returns the list of VM options.
+     *
+     * @return List of VM options
+     */
+    public static List<String> getVmOptions() {
+        return Arrays.asList(safeSplitString(VM_OPTIONS));
+    }
+
+    /**
+     * Returns the list of VM options with -J prefix.
+     *
+     * @return The list of VM options with -J prefix
+     */
+    public static List<String> getForwardVmOptions() {
+        String[] opts = safeSplitString(VM_OPTIONS);
+        for (int i = 0; i < opts.length; i++) {
+            opts[i] = "-J" + opts[i];
+        }
+        return Arrays.asList(opts);
+    }
+
+    /**
+     * Returns the default JTReg arguments for a jvm running a test.
+     * This is the combination of JTReg arguments test.vm.opts and test.java.opts.
+     * @return An array of options, or an empty array if no opptions.
+     */
+    public static String[] getTestJavaOpts() {
+        List<String> opts = new ArrayList<String>();
+        Collections.addAll(opts, safeSplitString(VM_OPTIONS));
+        Collections.addAll(opts, safeSplitString(JAVA_OPTIONS));
+        return opts.toArray(new String[0]);
+    }
+
+    /**
+     * Combines given arguments with default JTReg arguments for a jvm running a test.
+     * This is the combination of JTReg arguments test.vm.opts and test.java.opts
+     * @return The combination of JTReg test java options and user args.
+     */
+    public static String[] addTestJavaOpts(String... userArgs) {
+        List<String> opts = new ArrayList<String>();
+        Collections.addAll(opts, getTestJavaOpts());
+        Collections.addAll(opts, userArgs);
+        return opts.toArray(new String[0]);
+    }
+
+    /**
+     * Splits a string by white space.
+     * Works like String.split(), but returns an empty array
+     * if the string is null or empty.
+     */
+    private static String[] safeSplitString(String s) {
+        if (s == null || s.trim().isEmpty()) {
+            return new String[] {};
+        }
+        return s.trim().split("\\s+");
+    }
+
+    /**
+     * @return The full command line for the ProcessBuilder.
+     */
+    public static String getCommandLine(ProcessBuilder pb) {
+        StringBuilder cmd = new StringBuilder();
+        for (String s : pb.command()) {
+            cmd.append(s).append(" ");
+        }
+        return cmd.toString();
+    }
+
+    /**
+     * Returns the free port on the local host.
+     * The function will spin until a valid port number is found.
+     *
+     * @return The port number
+     * @throws InterruptedException if any thread has interrupted the current thread
+     * @throws IOException if an I/O error occurs when opening the socket
+     */
+    public static int getFreePort() throws InterruptedException, IOException {
+        int port = -1;
+
+        while (port <= 0) {
+            Thread.sleep(100);
+
+            ServerSocket serverSocket = null;
+            try {
+                serverSocket = new ServerSocket(0);
+                port = serverSocket.getLocalPort();
+            } finally {
+                serverSocket.close();
+            }
+        }
+
+        return port;
+    }
+
+    /**
+     * Returns the name of the local host.
+     *
+     * @return The host name
+     * @throws UnknownHostException if IP address of a host could not be determined
+     */
+    public static String getHostname() throws UnknownHostException {
+        InetAddress inetAddress = InetAddress.getLocalHost();
+        String hostName = inetAddress.getHostName();
+
+        assertTrue((hostName != null && !hostName.isEmpty()),
+                "Cannot get hostname");
+
+        return hostName;
+    }
+
+    /**
+     * Uses "jcmd -l" to search for a jvm pid. This function will wait
+     * forever (until jtreg timeout) for the pid to be found.
+     * @param key Regular expression to search for
+     * @return The found pid.
+     */
+    public static int waitForJvmPid(String key) throws Throwable {
+        final long iterationSleepMillis = 250;
+        System.out.println("waitForJvmPid: Waiting for key '" + key + "'");
+        System.out.flush();
+        while (true) {
+            int pid = tryFindJvmPid(key);
+            if (pid >= 0) {
+                return pid;
+            }
+            Thread.sleep(iterationSleepMillis);
+        }
+    }
+
+    /**
+     * Searches for a jvm pid in the output from "jcmd -l".
+     *
+     * Example output from jcmd is:
+     * 12498 sun.tools.jcmd.JCmd -l
+     * 12254 /tmp/jdk8/tl/jdk/JTwork/classes/com/sun/tools/attach/Application.jar
+     *
+     * @param key A regular expression to search for.
+     * @return The found pid, or -1 if Enot found.
+     * @throws Exception If multiple matching jvms are found.
+     */
+    public static int tryFindJvmPid(String key) throws Throwable {
+        ProcessBuilder pb = null;
+        OutputAnalyzer output = null;
+        try {
+            JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd");
+            jcmdLauncher.addToolArg("-l");
+            output = ProcessTools.executeProcess(jcmdLauncher.getCommand());
+            output.shouldHaveExitValue(0);
+
+            // Search for a line starting with numbers (pid), follwed by the key.
+            Pattern pattern = Pattern.compile("([0-9]+)\\s.*(" + key + ").*\\r?\\n");
+            Matcher matcher = pattern.matcher(output.getStdout());
+
+            int pid = -1;
+            if (matcher.find()) {
+                pid = Integer.parseInt(matcher.group(1));
+                System.out.println("findJvmPid.pid: " + pid);
+                if (matcher.find()) {
+                    throw new Exception("Found multiple JVM pids for key: " + key);
+                }
+            }
+            return pid;
+        } catch (Throwable t) {
+            System.out.println(String.format("Utils.findJvmPid(%s) failed: %s", key, t));
+            throw t;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/XRun.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+/**
+ * This type serves no other purpose than to simply allow automatically running
+ * something in a thread, and have all exceptions propagated to
+ * RuntimeExceptions, which are thrown up to thread, which in turn should
+ * probably be a {@link TestThread} to they are stored.
+ */
+public abstract class XRun implements Runnable {
+
+    /**
+     * Invokes {@code xrun()} and throws all exceptions caught in it
+     * up to the thread.
+     */
+    public final void run() {
+        try {
+            xrun();
+        } catch (Error e) {
+            throw e;
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Override this method to implement what to run in the thread.
+     *
+     * @throws Throwable
+     */
+    protected abstract void xrun() throws Throwable;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/java2d/DrawXORModeTest.java	Thu Mar 27 00:19:41 2014 +0000
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2014, 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
+ * @bug     8036022
+ * @summary Test verifies that drawing shapes with XOR composite
+ *          does not trigger an InternalError in GDI surface data.
+ * @run main/othervm -Dsun.java2d.d3d=True DrawXORModeTest
+ */
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Stroke;
+import java.awt.geom.Line2D;
+import java.util.concurrent.CountDownLatch;
+
+public class DrawXORModeTest extends Component {
+
+    public static void main(String[] args) {
+        final DrawXORModeTest c = new DrawXORModeTest();
+
+        final Frame f = new Frame("XOR mode test");
+        f.add(c);
+        f.pack();
+
+        f.setVisible(true);
+
+        try {
+            c.checkResult();
+        } finally {
+            f.dispose();
+        }
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        if (g == null || !(g instanceof Graphics2D)) {
+            return;
+        }
+        g.setColor(Color.white);
+        g.setXORMode(Color.black);
+        Graphics2D dg = (Graphics2D) g;
+        Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
+                BasicStroke.JOIN_MITER,
+                10.0f,
+                new float[]{1.0f, 1.0f},
+                0.0f);
+        dg.setStroke(stroke);
+        try {
+            dg.draw(new Line2D.Float(10, 10, 20, 20));
+        } catch (Throwable e) {
+            synchronized (this) {
+                theError = e;
+            }
+        } finally {
+            didDraw.countDown();
+        }
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        return new Dimension(400, 100);
+    }
+
+    public void checkResult() {
+        try {
+            didDraw.await();
+        } catch (InterruptedException e) {
+        }
+
+        synchronized (this) {
+            if (theError != null) {
+                System.out.println("Error: " + theError);
+
+                throw new RuntimeException("Test FAILED.");
+            }
+        }
+        System.out.println("Test PASSED.");
+
+    }
+
+    private Throwable theError = null;
+
+    private final CountDownLatch didDraw = new CountDownLatch(1);
+}