Merge tag jb8u242-b1644.3

Change-Id: Ia7492bb2a38c1c41216929de6ba6a0a553bd4338
diff --git a/.hgtags b/.hgtags
index 3a84abd..2aee5e5 100644
--- a/.hgtags
+++ b/.hgtags
@@ -1018,3 +1018,12 @@
 69c4f673b33e255599d2aa257fa50fd8b48b7b95 jdk8u232-b08
 5456f24496f43f72b0cf4f0db3a73ea49c33f94f jdk8u232-b09
 5456f24496f43f72b0cf4f0db3a73ea49c33f94f jdk8u232-ga
+d32fc856e071ff49c8a4c94682caad57f6c6874f jdk8u242-b01
+2b292ab0ed9af9aa8aab27b1a80daa3509a050ba jdk8u242-b02
+2f564a16517d678f31a3fa7352e16702e48c417d jdk8u242-b03
+8163e59959ed5462891f2b1db7bc0fa2af1de0a6 jdk8u242-b04
+b2865f7f557fcaec84445b034b2de2b27456b6c5 jdk8u242-b05
+0d27e60569f7cf85cbdb0a83436e772e9256b5b0 jdk8u242-b06
+034a65a05bfbfb06e14d3d39efa0c9f27683573a jdk8u242-b07
+c63c2923e1f99c1f350bd24b42daf885023f18b7 jdk8u242-b08
+c63c2923e1f99c1f350bd24b42daf885023f18b7 jdk8u242-ga
diff --git a/THIRD_PARTY_README b/THIRD_PARTY_README
index 7dc54a0..643ea79 100644
--- a/THIRD_PARTY_README
+++ b/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
 
 --------------------------------------------------------------------------------
 
-%% This notice is provided with respect to Joni v1.1.9, which may be 
+%% This notice is provided with respect to Joni v2.1.16, which may be
 included with JRE 8, JDK 8, and OpenJDK 8.
 
 --- begin of LICENSE ---
 
+Copyright (c) 2017 JRuby Team
+
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
diff --git a/build.txt b/build.txt
index d2d3011..58c76cf 100644
--- a/build.txt
+++ b/build.txt
@@ -1 +1 @@
-8u232-b1638.6
+8u242-b1644.3
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
diff --git a/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java b/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java
index c693eed..ba83f92 100644
--- a/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java
+++ b/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java
@@ -4,7 +4,9 @@
  *
  * 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.
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
diff --git a/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c b/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c
index b65457c..a9985fa 100644
--- a/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c
+++ b/make/src/native/add_gnu_debuglink/add_gnu_debuglink.c
@@ -4,7 +4,9 @@
  *
  * 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.
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
diff --git a/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c b/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c
index 68bd093..fc583ec 100644
--- a/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c
+++ b/make/src/native/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c
@@ -4,7 +4,9 @@
  *
  * 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.
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
diff --git a/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java b/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
index 89911b8..5606e98 100644
--- a/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
+++ b/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
@@ -42,7 +42,6 @@
 import java.awt.image.DirectColorModel;
 import java.awt.image.VolatileImage;
 import java.awt.image.WritableRaster;
-import java.util.HashMap;
 import java.util.concurrent.Callable;
 
 import sun.awt.CGraphicsConfig;
@@ -89,8 +88,6 @@
                                                 int swapInterval);
     private static native int getOGLCapabilities(long configInfo);
 
-    private static final HashMap<Long, Integer> pGCRefCounts = new HashMap<>();
-
     /**
      * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
      * called under OGLRQ lock, because this method change current context.
@@ -113,7 +110,7 @@
         this.oglCaps = oglCaps;
         this.maxTextureSize = maxTextureSize;
         context = new OGLContext(OGLRenderQueue.getInstance(), this);
-        refPConfigInfo(pConfigInfo);
+
         // add a record to the Disposer so that we destroy the native
         // CGLGraphicsConfigInfo data when this object goes away
         Disposer.addRecord(disposerReferent,
@@ -193,33 +190,6 @@
                 });
     }
 
-    static void refPConfigInfo(long pConfigInfo) {
-        synchronized (pGCRefCounts) {
-            Integer count = pGCRefCounts.get(pConfigInfo);
-            if (count == null) {
-                count = 1;
-            }
-            else {
-                count++;
-            }
-            pGCRefCounts.put(pConfigInfo, count);
-        }
-    }
-
-    static void deRefPConfigInfo(long pConfigInfo) {
-        synchronized (pGCRefCounts) {
-            Integer count = pGCRefCounts.get(pConfigInfo);
-            if (count != null) {
-                count--;
-                pGCRefCounts.put(pConfigInfo, count);
-                if (count == 0) {
-                    OGLRenderQueue.disposeGraphicsConfig(pConfigInfo);
-                    pGCRefCounts.remove(pConfigInfo);
-                }
-            }
-        }
-    }
-
     public static boolean isCGLAvailable() {
         return cglAvailable;
     }
@@ -287,7 +257,7 @@
         }
         public void dispose() {
             if (pCfgInfo != 0) {
-                deRefPConfigInfo(pCfgInfo);
+                OGLRenderQueue.disposeGraphicsConfig(pCfgInfo);
                 pCfgInfo = 0;
             }
         }
diff --git a/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java b/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java
index 39f2e49..6083faa 100644
--- a/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java
+++ b/src/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -48,8 +48,9 @@
 
     native void validate(int xoff, int yoff, int width, int height, boolean isOpaque);
 
-    private native void initOps(long pConfigInfo, long pPeerData, long layerPtr,
-                                int xoff, int yoff, boolean isOpaque);
+    private native void initOps(OGLGraphicsConfig gc, long pConfigInfo,
+                                long pPeerData, long layerPtr, int xoff,
+                                int yoff, boolean isOpaque);
 
     protected native boolean initPbuffer(long pData, long pConfigInfo,
             boolean isOpaque, int width, int height);
@@ -77,8 +78,7 @@
             pPeerData = pView.getAWTView();
             isOpaque = pView.isOpaque();
         }
-        CGLGraphicsConfig.refPConfigInfo(pConfigInfo);
-        initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
+        initOps(gc, pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
     }
 
     protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
@@ -94,8 +94,7 @@
             layerPtr = layer.getPointer();
             isOpaque = layer.isOpaque();
         }
-        CGLGraphicsConfig.refPConfigInfo(pConfigInfo);
-        initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
+        initOps(gc, pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
     }
 
     @Override //SurfaceData
@@ -385,9 +384,4 @@
             destroyCGLContext(ctx);
         }
     }
-
-    static void dispose(long pData, long pConfigInfo) {
-        OGLSurfaceData.dispose(pData, pConfigInfo);
-        CGLGraphicsConfig.deRefPConfigInfo(pConfigInfo);
-    }
 }
diff --git a/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser b/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser
index cda3de5..dd674ec 100644
--- a/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser
+++ b/src/macosx/native/jobjc/JObjC.xcodeproj/default.pbxuser
@@ -5,7 +5,9 @@
  *
  * 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.
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
diff --git a/src/macosx/native/sun/awt/CGraphicsDevice.m b/src/macosx/native/sun/awt/CGraphicsDevice.m
index 6a22c65..570c4d6 100644
--- a/src/macosx/native/sun/awt/CGraphicsDevice.m
+++ b/src/macosx/native/sun/awt/CGraphicsDevice.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -94,16 +94,18 @@
 static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) {
     CGDisplayModeRef bestGuess = NULL;
     CFIndex numModes = CFArrayGetCount(allModes), n;
-    int thisBpp = 0;
+
     for(n = 0; n < numModes; n++ ) {
         CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
         if(cRef == NULL) {
             continue;
         }
         CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef);
-        thisBpp = getBPPFromModeString(modeString);
+        int thisBpp = getBPPFromModeString(modeString);
         CFRelease(modeString);
-        if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) {
+        int thisH = (int)CGDisplayModeGetHeight(cRef);
+        int thisW = (int)CGDisplayModeGetWidth(cRef);
+        if (thisBpp != bpp || thisH != h || thisW != w) {
             // One of the key parameters does not match
             continue;
         }
@@ -114,11 +116,12 @@
 
         // Refresh rate might be 0 in display mode and we ask for specific display rate
         // but if we do not find exact match then 0 refresh rate might be just Ok
-        if (CGDisplayModeGetRefreshRate(cRef) == refrate) {
+        int thisRefrate = (int)CGDisplayModeGetRefreshRate(cRef);
+        if (thisRefrate == refrate) {
             // Exact match
             return cRef;
         }
-        if (CGDisplayModeGetRefreshRate(cRef) == 0) {
+        if (thisRefrate == 0) {
             // Not exactly what was asked for, but may fit our needs if we don't find an exact match
             bestGuess = cRef;
         }
diff --git a/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m b/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m
index d4c1d71..0c32ac3 100644
--- a/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m
+++ b/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m
@@ -145,31 +145,6 @@
 }
 
 /**
- * Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo
- * associated with the given OGLSDOps.  This method can be called from
- * shared code to retrieve the native GraphicsConfig data in a platform-
- * independent manner.
- */
-jlong
-OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
-{
-    J2dTraceLn(J2D_TRACE_INFO, "OGLSD_GetNativeConfigInfo");
-
-    if (oglsdo == NULL) {
-        J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: ops are null");
-        return 0L;
-    }
-
-    CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
-    if (cglsdo == NULL) {
-        J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: cgl ops are null");
-        return 0L;
-    }
-
-    return ptr_to_jlong(cglsdo->configInfo);
-}
-
-/**
  * Makes the given GraphicsConfig's context current to its associated
  * "scratch" surface.  If there is a problem making the context current,
  * this method will return NULL; otherwise, returns a pointer to the
@@ -409,21 +384,9 @@
 extern UnlockFunc      OGLSD_Unlock;
 extern DisposeFunc     OGLSD_Dispose;
 
-
-void
-CGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
-{
-    OGLSDOps *oglsdo = (OGLSDOps *)ops;
-    jlong pConfigInfo = OGLSD_GetNativeConfigInfo(oglsdo);
-    JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/CGLSurfaceData",
-                               "dispose", "(JJ)V",
-                               ptr_to_jlong(ops), pConfigInfo);
-}
-
-
 JNIEXPORT void JNICALL
 Java_sun_java2d_opengl_CGLSurfaceData_initOps
-    (JNIEnv *env, jobject cglsd,
+    (JNIEnv *env, jobject cglsd, jobject gc,
      jlong pConfigInfo, jlong pPeerData, jlong layerPtr,
      jint xoff, jint yoff, jboolean isOpaque)
 {
@@ -431,8 +394,22 @@
     J2dTraceLn1(J2D_TRACE_INFO, "  pPeerData=%p", jlong_to_ptr(pPeerData));
     J2dTraceLn2(J2D_TRACE_INFO, "  xoff=%d, yoff=%d", (int)xoff, (int)yoff);
 
+    gc = (*env)->NewGlobalRef(env, gc);
+    if (gc == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+        return;
+    }
+
     OGLSDOps *oglsdo = (OGLSDOps *)
         SurfaceData_InitOps(env, cglsd, sizeof(OGLSDOps));
+    if (oglsdo == NULL) {
+        (*env)->DeleteGlobalRef(env, gc);
+        JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+        return;
+    }
+    // later the graphicsConfig will be used for deallocation of oglsdo
+    oglsdo->graphicsConfig = gc;
+
     CGLSDOps *cglsdo = (CGLSDOps *)malloc(sizeof(CGLSDOps));
     if (cglsdo == NULL) {
         JNU_ThrowOutOfMemoryError(env, "creating native cgl ops");
@@ -444,7 +421,7 @@
     oglsdo->sdOps.Lock               = OGLSD_Lock;
     oglsdo->sdOps.GetRasInfo         = OGLSD_GetRasInfo;
     oglsdo->sdOps.Unlock             = OGLSD_Unlock;
-    oglsdo->sdOps.Dispose            = CGLSD_Dispose;
+    oglsdo->sdOps.Dispose            = OGLSD_Dispose;
 
     oglsdo->drawableType = OGLSD_UNDEFINED;
     oglsdo->activeBuffer = GL_FRONT;
diff --git a/src/share/classes/com/sun/crypto/provider/GHASH.java b/src/share/classes/com/sun/crypto/provider/GHASH.java
index ee747c8..dc42e6b 100644
--- a/src/share/classes/com/sun/crypto/provider/GHASH.java
+++ b/src/share/classes/com/sun/crypto/provider/GHASH.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2015 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -62,14 +62,16 @@
 
     private static final int AES_BLOCK_SIZE = 16;
 
-    // Multiplies state0, state1 by V0, V1.
-    private void blockMult(long V0, long V1) {
+    // Multiplies state[0], state[1] by subkeyH[0], subkeyH[1].
+    private static void blockMult(long[] st, long[] subH) {
         long Z0 = 0;
         long Z1 = 0;
+        long V0 = subH[0];
+        long V1 = subH[1];
         long X;
 
-        // Separate loops for processing state0 and state1.
-        X = state0;
+        // Separate loops for processing state[0] and state[1].
+        X = st[0];
         for (int i = 0; i < 64; i++) {
             // Zi+1 = Zi if bit i of x is 0
             long mask = X >> 63;
@@ -89,7 +91,7 @@
             X <<= 1;
         }
 
-        X = state1;
+        X = st[1];
         for (int i = 64; i < 127; i++) {
             // Zi+1 = Zi if bit i of x is 0
             long mask = X >> 63;
@@ -115,15 +117,18 @@
         Z1 ^= V1 & mask;
 
         // Save result.
-        state0 = Z0;
-        state1 = Z1;
+        st[0] = Z0;
+        st[1] = Z1;
+
     }
 
+    /* subkeyH and state are stored in long[] for GHASH intrinsic use */
+
     // hash subkey H; should not change after the object has been constructed
-    private final long subkeyH0, subkeyH1;
+    private final long[] subkeyH;
 
     // buffer for storing hash
-    private long state0, state1;
+    private final long[] state;
 
     // variables for save/restore calls
     private long stateSave0, stateSave1;
@@ -141,8 +146,10 @@
         if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
             throw new ProviderException("Internal error");
         }
-        this.subkeyH0 = getLong(subkeyH, 0);
-        this.subkeyH1 = getLong(subkeyH, 8);
+        state = new long[2];
+        this.subkeyH = new long[2];
+        this.subkeyH[0] = getLong(subkeyH, 0);
+        this.subkeyH[1] = getLong(subkeyH, 8);
     }
 
     /**
@@ -151,33 +158,30 @@
      * this object for different data w/ the same H.
      */
     void reset() {
-        state0 = 0;
-        state1 = 0;
+        state[0] = 0;
+        state[1] = 0;
     }
 
     /**
      * Save the current snapshot of this GHASH object.
      */
     void save() {
-        stateSave0 = state0;
-        stateSave1 = state1;
+        stateSave0 = state[0];
+        stateSave1 = state[1];
     }
 
     /**
      * Restores this object using the saved snapshot.
      */
     void restore() {
-        state0 = stateSave0;
-        state1 = stateSave1;
+        state[0] = stateSave0;
+        state[1] = stateSave1;
     }
 
-    private void processBlock(byte[] data, int ofs) {
-        if (data.length - ofs < AES_BLOCK_SIZE) {
-            throw new RuntimeException("need complete block");
-        }
-        state0 ^= getLong(data, ofs);
-        state1 ^= getLong(data, ofs + 8);
-        blockMult(subkeyH0, subkeyH1);
+    private static void processBlock(byte[] data, int ofs, long[] st, long[] subH) {
+        st[0] ^= getLong(data, ofs);
+        st[1] ^= getLong(data, ofs + 8);
+        blockMult(st, subH);
     }
 
     void update(byte[] in) {
@@ -185,22 +189,57 @@
     }
 
     void update(byte[] in, int inOfs, int inLen) {
-        if (inLen - inOfs > in.length) {
-            throw new RuntimeException("input length out of bound");
+        if (inLen == 0) {
+            return;
+        }
+        ghashRangeCheck(in, inOfs, inLen, state, subkeyH);
+        processBlocks(in, inOfs, inLen/AES_BLOCK_SIZE, state, subkeyH);
+    }
+
+    private static void ghashRangeCheck(byte[] in, int inOfs, int inLen, long[] st, long[] subH) {
+        if (inLen < 0) {
+            throw new RuntimeException("invalid input length: " + inLen);
+        }
+        if (inOfs < 0) {
+            throw new RuntimeException("invalid offset: " + inOfs);
+        }
+        if (inLen > in.length - inOfs) {
+            throw new RuntimeException("input length out of bound: " +
+                                       inLen + " > " + (in.length - inOfs));
         }
         if (inLen % AES_BLOCK_SIZE != 0) {
-            throw new RuntimeException("input length unsupported");
+            throw new RuntimeException("input length/block size mismatch: " +
+                                       inLen);
         }
 
-        for (int i = inOfs; i < (inOfs + inLen); i += AES_BLOCK_SIZE) {
-            processBlock(in, i);
+        // These two checks are for C2 checking
+        if (st.length != 2) {
+            throw new RuntimeException("internal state has invalid length: " +
+                                       st.length);
+        }
+        if (subH.length != 2) {
+            throw new RuntimeException("internal subkeyH has invalid length: " +
+                                       subH.length);
+        }
+    }
+    /*
+     * This is an intrinsified method.  The method's argument list must match
+     * the hotspot signature.  This method and methods called by it, cannot
+     * throw exceptions or allocate arrays as it will breaking intrinsics
+     */
+    private static void processBlocks(byte[] data, int inOfs, int blocks, long[] st, long[] subH) {
+        int offset = inOfs;
+        while (blocks > 0) {
+            processBlock(data, offset, st, subH);
+            blocks--;
+            offset += AES_BLOCK_SIZE;
         }
     }
 
     byte[] digest() {
         byte[] result = new byte[AES_BLOCK_SIZE];
-        putLong(result, 0, state0);
-        putLong(result, 8, state1);
+        putLong(result, 0, state[0]);
+        putLong(result, 8, state[1]);
         reset();
         return result;
     }
diff --git a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
index d47f5a9..d05dcac 100644
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
+++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
@@ -43,6 +43,7 @@
 import java.security.cert.CertificateException;
 import javax.crypto.SealedObject;
 
+import sun.misc.IOUtils;
 import sun.misc.ObjectInputFilter;
 
 /**
@@ -70,7 +71,7 @@
     private static final class PrivateKeyEntry {
         Date date; // the creation date of this entry
         byte[] protectedKey;
-        Certificate chain[];
+        Certificate[] chain;
     };
 
     // Secret key
@@ -738,23 +739,11 @@
                         entry.date = new Date(dis.readLong());
 
                         // read the private key
-                        try {
-                            entry.protectedKey = new byte[dis.readInt()];
-                        } catch (OutOfMemoryError e) {
-                            throw new IOException("Keysize too big");
-                        }
-                        dis.readFully(entry.protectedKey);
+                        entry.protectedKey = IOUtils.readExactlyNBytes(dis, dis.readInt());
 
                         // read the certificate chain
                         int numOfCerts = dis.readInt();
-                        try {
-                            if (numOfCerts > 0) {
-                                entry.chain = new Certificate[numOfCerts];
-                            }
-                        } catch (OutOfMemoryError e) {
-                            throw new IOException("Too many certificates in "
-                                                  + "chain");
-                        }
+                        List<Certificate> tmpCerts = new ArrayList<>();
                         for (int j = 0; j < numOfCerts; j++) {
                             if (xVersion == 2) {
                                 // read the certificate type, and instantiate a
@@ -762,27 +751,24 @@
                                 // existing factory if possible)
                                 String certType = dis.readUTF();
                                 if (cfs.containsKey(certType)) {
-                                // reuse certificate factory
+                                    // reuse certificate factory
                                     cf = cfs.get(certType);
                                 } else {
-                                // create new certificate factory
+                                    // create new certificate factory
                                     cf = CertificateFactory.getInstance(
                                         certType);
-                                // store the certificate factory so we can
-                                // reuse it later
+                                    // store the certificate factory so we can
+                                    // reuse it later
                                     cfs.put(certType, cf);
                                 }
                             }
                             // instantiate the certificate
-                            try {
-                                encoded = new byte[dis.readInt()];
-                            } catch (OutOfMemoryError e) {
-                                throw new IOException("Certificate too big");
-                            }
-                            dis.readFully(encoded);
+                            encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                             bais = new ByteArrayInputStream(encoded);
-                            entry.chain[j] = cf.generateCertificate(bais);
+                            tmpCerts.add(cf.generateCertificate(bais));
                         }
+                        entry.chain = tmpCerts.toArray(
+                                new Certificate[numOfCerts]);
 
                         // Add the entry to the list
                         entries.put(alias, entry);
@@ -814,12 +800,7 @@
                                 cfs.put(certType, cf);
                             }
                         }
-                        try {
-                            encoded = new byte[dis.readInt()];
-                        } catch (OutOfMemoryError e) {
-                            throw new IOException("Certificate too big");
-                        }
-                        dis.readFully(encoded);
+                        encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                         bais = new ByteArrayInputStream(encoded);
                         entry.cert = cf.generateCertificate(bais);
 
@@ -870,18 +851,14 @@
                  * with
                  */
                 if (password != null) {
-                    byte computed[], actual[];
-                    computed = md.digest();
-                    actual = new byte[computed.length];
-                    dis.readFully(actual);
-                    for (int i = 0; i < computed.length; i++) {
-                        if (computed[i] != actual[i]) {
-                            throw new IOException(
+                    byte[] computed = md.digest();
+                    byte[] actual = IOUtils.readExactlyNBytes(dis, computed.length);
+                    if (!MessageDigest.isEqual(computed, actual)) {
+                        throw new IOException(
                                 "Keystore was tampered with, or "
                                 + "password was incorrect",
-                                    new UnrecoverableKeyException(
-                                            "Password verification failed"));
-                        }
+                                new UnrecoverableKeyException(
+                                        "Password verification failed"));
                     }
                 }
             }  finally {
diff --git a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
index 3da159f..e86e60e 100644
--- a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
+++ b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
@@ -123,6 +123,13 @@
         return e;
     }
 
+    private Entry checkValid(Entry e) {
+         if (e == INVALID_ENTRY) {
+            throw new IllegalStateException("Invalid constant pool reference");
+        }
+         return e;
+    }
+
     /** Throw a ClassFormatException if the entry does not match the expected tag type. */
     private Entry checkTag(Entry e, byte tag) throws ClassFormatException {
         if (e == null || !e.tagMatches(tag)) {
@@ -225,6 +232,29 @@
         return null;  // OK
     }
 
+    // use this identity for invalid references
+    private static final Entry INVALID_ENTRY = new Entry((byte) -1) {
+        @Override
+        public boolean equals(Object o) {
+            throw new IllegalStateException("Should not call this");
+        }
+
+        @Override
+        protected int computeValueHash() {
+            throw new IllegalStateException("Should not call this");
+        }
+
+        @Override
+        public int compareTo(Object o) {
+            throw new IllegalStateException("Should not call this");
+        }
+
+        @Override
+        public String stringValue() {
+            throw new IllegalStateException("Should not call this");
+        }
+    };
+
     void readConstantPool() throws IOException {
         int length = in.readUnsignedShort();
         //System.err.println("reading CP, length="+length);
@@ -233,7 +263,7 @@
         int fptr = 0;
 
         Entry[] cpMap = new Entry[length];
-        cpMap[0] = null;
+        cpMap[0] = INVALID_ENTRY;
         for (int i = 1; i < length; i++) {
             //System.err.println("reading CP elt, i="+i);
             int tag = in.readByte();
@@ -254,13 +284,13 @@
                 case CONSTANT_Long:
                     {
                         cpMap[i] = ConstantPool.getLiteralEntry(in.readLong());
-                        cpMap[++i] = null;
+                        cpMap[++i] = INVALID_ENTRY;
                     }
                     break;
                 case CONSTANT_Double:
                     {
                         cpMap[i] = ConstantPool.getLiteralEntry(in.readDouble());
-                        cpMap[++i] = null;
+                        cpMap[++i] = INVALID_ENTRY;
                     }
                     break;
 
@@ -315,7 +345,7 @@
                 int ref2 = fixups[fi++];
                 if (verbose > 3)
                     Utils.log.fine("  cp["+cpi+"] = "+ConstantPool.tagName(tag)+"{"+ref+","+ref2+"}");
-                if (ref >= 0 && cpMap[ref] == null || ref2 >= 0 && cpMap[ref2] == null) {
+                if (ref >= 0 && checkValid(cpMap[ref]) == null || ref2 >= 0 && checkValid(cpMap[ref2]) == null) {
                     // Defer.
                     fixups[fptr++] = cpi;
                     fixups[fptr++] = tag;
@@ -364,7 +394,6 @@
 
         cls.cpMap = cpMap;
     }
-
     private /*non-static*/
     class UnresolvedEntry extends Entry {
         final Object[] refsOrIndexes;
diff --git a/src/share/classes/com/sun/jndi/ldap/Connection.java b/src/share/classes/com/sun/jndi/ldap/Connection.java
index 43e83c1..e36670e 100644
--- a/src/share/classes/com/sun/jndi/ldap/Connection.java
+++ b/src/share/classes/com/sun/jndi/ldap/Connection.java
@@ -47,8 +47,6 @@
 import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLSocket;
 
-import sun.misc.IOUtils;
-
 /**
   * A thread that creates a connection to an LDAP server.
   * After the connection, the thread reads from the connection.
@@ -886,7 +884,7 @@
                     }
 
                     // read in seqlen bytes
-                    byte[] left = IOUtils.readFully(in, seqlen, false);
+                    byte[] left = readFully(in, seqlen);
                     inbuf = Arrays.copyOf(inbuf, offset + left.length);
                     System.arraycopy(left, 0, inbuf, offset, left.length);
                     offset += left.length;
@@ -981,6 +979,31 @@
         }
     }
 
+    private static byte[] readFully(InputStream is, int length)
+        throws IOException
+    {
+        byte[] buf = new byte[Math.min(length, 8192)];
+        int nread = 0;
+        while (nread < length) {
+            int bytesToRead;
+            if (nread >= buf.length) {  // need to allocate a larger buffer
+                bytesToRead = Math.min(length - nread, buf.length + 8192);
+                if (buf.length < nread + bytesToRead) {
+                    buf = Arrays.copyOf(buf, nread + bytesToRead);
+                }
+            } else {
+                bytesToRead = buf.length - nread;
+            }
+            int count = is.read(buf, nread, bytesToRead);
+            if (count < 0) {
+                if (buf.length != nread)
+                    buf = Arrays.copyOf(buf, nread);
+                break;
+            }
+            nread += count;
+        }
+        return buf;
+    }
 
     // This code must be uncommented to run the LdapAbandonTest.
     /*public void sendSearchReqs(String dn, int numReqs) {
diff --git a/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java b/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
index 8547363..448764c 100644
--- a/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
+++ b/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
@@ -123,8 +123,9 @@
  * must also be set to true; Otherwise a configuration error will
  * be returned.</dd>
  * <dt><b><code>renewTGT</code></b>:</dt>
- * <dd>Set this to true, if you want to renew
- * the TGT. If this is set, <code>useTicketCache</code> must also be
+ * <dd>Set this to true, if you want to renew the TGT when it's more than
+ * half-way expired (the time until expiration is less than the time
+ * since start time). If this is set, {@code useTicketCache} must also be
  * set to true; otherwise a configuration error will be returned.</dd>
  * <dt><b><code>doNotPrompt</code></b>:</dt>
  * <dd>Set this to true if you do not want to be
@@ -665,22 +666,21 @@
                     (principal, ticketCacheName);
 
                 if (cred != null) {
-                    // check to renew credentials
-                    if (!isCurrent(cred)) {
-                        if (renewTGT) {
-                            Credentials newCred = renewCredentials(cred);
-                            if (newCred != null) {
-                                newCred.setProxy(cred.getProxy());
-                            }
+                    if (renewTGT && isOld(cred)) {
+                        // renew if ticket is old.
+                        Credentials newCred = renewCredentials(cred);
+                        if (newCred != null) {
+                            newCred.setProxy(cred.getProxy());
                             cred = newCred;
-                        } else {
-                            // credentials have expired
-                            cred = null;
-                            if (debug)
-                                System.out.println("Credentials are" +
-                                                " no longer valid");
                         }
                     }
+                    if (!isCurrent(cred)) {
+                        // credentials have expired
+                        cred = null;
+                        if (debug)
+                            System.out.println("Credentials are" +
+                                    " no longer valid");
+                    }
                 }
 
                 if (cred != null) {
@@ -988,7 +988,7 @@
         }
     }
 
-    private boolean isCurrent(Credentials creds)
+    private static boolean isCurrent(Credentials creds)
     {
         Date endTime = creds.getEndTime();
         if (endTime != null) {
@@ -997,6 +997,23 @@
         return true;
     }
 
+    private static boolean isOld(Credentials creds)
+    {
+        Date endTime = creds.getEndTime();
+        if (endTime != null) {
+            Date authTime = creds.getAuthTime();
+            long now = System.currentTimeMillis();
+            if (authTime != null) {
+                // pass the mid between auth and end
+                return now - authTime.getTime() > endTime.getTime() - now;
+            } else {
+                // will expire in less than 2 hours
+                return now <= endTime.getTime() - 1000*3600*2L;
+            }
+        }
+        return false;
+    }
+
     private Credentials renewCredentials(Credentials creds)
     {
         Credentials lcreds;
@@ -1004,6 +1021,10 @@
             if (!creds.isRenewable())
                 throw new RefreshFailedException("This ticket" +
                                 " is not renewable");
+            if (creds.getRenewTill() == null) {
+                // Renewable ticket without renew-till. Illegal and ignored.
+                return creds;
+            }
             if (System.currentTimeMillis() > cred.getRenewTill().getTime())
                 throw new RefreshFailedException("This ticket is past "
                                              + "its last renewal time.");
diff --git a/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java b/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java
index 30461e2..baa836e 100644
--- a/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java
+++ b/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -73,8 +73,12 @@
         }
 
         try {
-            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
+            MessageProp msgProp = new MessageProp(JGSS_QOP, false);
             byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
+            if (privacy && !msgProp.getPrivacy()) {
+                throw new SaslException("Privacy not protected");
+            }
+            checkMessageProp("", msgProp);
             if (logger.isLoggable(Level.FINEST)) {
                 traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
                     incoming, start, len);
@@ -128,4 +132,20 @@
     protected void finalize() throws Throwable {
         dispose();
     }
+
+    void checkMessageProp(String label, MessageProp msgProp)
+            throws SaslException {
+        if (msgProp.isDuplicateToken()) {
+            throw new SaslException(label + "Duplicate token");
+        }
+        if (msgProp.isGapToken()) {
+            throw new SaslException(label + "Gap token");
+        }
+        if (msgProp.isOldToken()) {
+            throw new SaslException(label + "Old token");
+        }
+        if (msgProp.isUnseqToken()) {
+            throw new SaslException(label + "Token not in sequence");
+        }
+    }
 }
diff --git a/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java b/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
index e8d9a4c..34a879a 100644
--- a/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
+++ b/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -230,8 +230,10 @@
 
             // Received S1 (security layer, server max recv size)
 
+            MessageProp msgProp = new MessageProp(false);
             byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
-                challengeData.length, new MessageProp(0, false));
+                challengeData.length, msgProp);
+            checkMessageProp("Handshake failure: ", msgProp);
 
             // First octet is a bit-mask specifying the protections
             // supported by the server
diff --git a/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java b/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
index 94ce39c..10c429a 100644
--- a/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
+++ b/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -250,8 +250,10 @@
         try {
             // Expecting 4 octets from client selected protection
             // and client's receive buffer size
+            MessageProp msgProp = new MessageProp(false);
             byte[] gssOutToken = secCtx.unwrap(responseData, 0,
-                responseData.length, new MessageProp(0, false));
+                responseData.length, msgProp);
+            checkMessageProp("Handshake failure: ", msgProp);
 
             if (logger.isLoggable(Level.FINER)) {
                 traceOutput(MY_CLASS_NAME, "doHandshake2",
diff --git a/src/share/classes/java/awt/color/ICC_Profile.java b/src/share/classes/java/awt/color/ICC_Profile.java
index 89abeca..af1e5fc 100644
--- a/src/share/classes/java/awt/color/ICC_Profile.java
+++ b/src/share/classes/java/awt/color/ICC_Profile.java
@@ -43,7 +43,9 @@
 import sun.java2d.cmm.ProfileDeferralMgr;
 import sun.java2d.cmm.ProfileDeferralInfo;
 import sun.java2d.cmm.ProfileActivator;
+import sun.misc.IOUtils;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -1019,42 +1021,25 @@
 
 
     static byte[] getProfileDataFromStream(InputStream s) throws IOException {
-    byte profileData[];
-    int profileSize;
 
-        byte header[] = new byte[128];
-        int bytestoread = 128;
-        int bytesread = 0;
-        int n;
+        BufferedInputStream bis = new BufferedInputStream(s);
+        bis.mark(128);
 
-        while (bytestoread != 0) {
-            if ((n = s.read(header, bytesread, bytestoread)) < 0) {
-                return null;
-            }
-            bytesread += n;
-            bytestoread -= n;
-        }
+        byte[] header = IOUtils.readNBytes(bis, 128);
         if (header[36] != 0x61 || header[37] != 0x63 ||
             header[38] != 0x73 || header[39] != 0x70) {
             return null;   /* not a valid profile */
         }
-        profileSize = ((header[0] & 0xff) << 24) |
-                      ((header[1] & 0xff) << 16) |
-                      ((header[2] & 0xff) <<  8) |
-                       (header[3] & 0xff);
-        profileData = new byte[profileSize];
-        System.arraycopy(header, 0, profileData, 0, 128);
-        bytestoread = profileSize - 128;
-        bytesread = 128;
-        while (bytestoread != 0) {
-            if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
-                return null;
-            }
-            bytesread += n;
-            bytestoread -= n;
+        int profileSize = ((header[0] & 0xff) << 24) |
+                          ((header[1] & 0xff) << 16) |
+                          ((header[2] & 0xff) << 8) |
+                          (header[3] & 0xff);
+        bis.reset();
+        try {
+            return IOUtils.readNBytes(bis, profileSize);
+        } catch (OutOfMemoryError e) {
+            throw new IOException("Color profile is too big");
         }
-
-        return profileData;
     }
 
 
diff --git a/src/share/classes/java/beans/beancontext/BeanContextSupport.java b/src/share/classes/java/beans/beancontext/BeanContextSupport.java
index 43dfcb0..9ce1658 100644
--- a/src/share/classes/java/beans/beancontext/BeanContextSupport.java
+++ b/src/share/classes/java/beans/beancontext/BeanContextSupport.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -1024,18 +1024,8 @@
         int count = serializable;
 
         while (count-- > 0) {
-            Object                      child = null;
-            BeanContextSupport.BCSChild bscc  = null;
-
-            try {
-                child = ois.readObject();
-                bscc  = (BeanContextSupport.BCSChild)ois.readObject();
-            } catch (IOException ioe) {
-                continue;
-            } catch (ClassNotFoundException cnfe) {
-                continue;
-            }
-
+            Object child = ois.readObject();
+            BCSChild bscc = (BCSChild) ois.readObject();
 
             synchronized(child) {
                 BeanContextChild bcc = null;
diff --git a/src/share/classes/java/io/FilePermission.java b/src/share/classes/java/io/FilePermission.java
index 3e0f7d8..ae4a919 100644
--- a/src/share/classes/java/io/FilePermission.java
+++ b/src/share/classes/java/io/FilePermission.java
@@ -46,8 +46,11 @@
  * the file separator character, <code>File.separatorChar</code>) indicates
  * all the files and directories contained in that directory. A pathname
  * that ends with "/-" indicates (recursively) all files
- * and subdirectories contained in that directory. A pathname consisting of
- * the special token "&lt;&lt;ALL FILES&gt;&gt;" matches <b>any</b> file.
+ * and subdirectories contained in that directory. Such a pathname is called
+ * a wildcard pathname. Otherwise, it's a simple pathname.
+ * <P>
+ * A pathname consisting of the special token {@literal "<<ALL FILES>>"}
+ * matches <b>any</b> file.
  * <P>
  * Note: A pathname consisting of a single "*" indicates all the files
  * in the current directory, while a pathname consisting of a single "-"
@@ -80,7 +83,7 @@
  * <P>
  * Be careful when granting FilePermissions. Think about the implications
  * of granting read and especially write access to various files and
- * directories. The "&lt;&lt;ALL FILES&gt;&gt;" permission with write action is
+ * directories. The {@literal "<<ALL FILES>>"} permission with write action is
  * especially dangerous. This grants permission to write to the entire
  * file system. One thing this effectively allows is replacement of the
  * system binary, including the JVM runtime environment.
@@ -156,6 +159,7 @@
 
     private transient String cpath;
 
+    private transient boolean allFiles; // whether this is <<ALL FILES>>
     private transient boolean invalid;  // whether input path is invalid
 
     // static Strings used by init(int mask)
@@ -207,6 +211,7 @@
         this.mask = mask;
 
         if (cpath.equals("<<ALL FILES>>")) {
+            allFiles = true;
             directory = true;
             recursive = true;
             cpath = "";
@@ -335,6 +340,23 @@
      *      "/tmp/*" encompasses all files in the "/tmp" directory,
      *      including the one named "foo".
      * </ul>
+     * <P>
+     * Precisely, a simple pathname implies another simple pathname
+     * if and only if they are equal. A simple pathname never implies
+     * a wildcard pathname. A wildcard pathname implies another wildcard
+     * pathname if and only if all simple pathnames implied by the latter
+     * are implied by the former. A wildcard pathname implies a simple
+     * pathname if and only if
+     * <ul>
+     *     <li>if the wildcard flag is "*", the simple pathname's path
+     *     must be right inside the wildcard pathname's path.
+     *     <li>if the wildcard flag is "-", the simple pathname's path
+     *     must be recursively inside the wildcard pathname's path.
+     * </ul>
+     * <P>
+     * {@literal "<<ALL FILES>>"} implies every other pathname. No pathname,
+     * except for {@literal "<<ALL FILES>>"} itself, implies
+     * {@literal "<<ALL FILES>>"}.
      *
      * @param p the permission to check against.
      *
@@ -366,9 +388,15 @@
         if (this == that) {
             return true;
         }
+        if (allFiles) {
+            return true;
+        }
         if (this.invalid || that.invalid) {
             return false;
         }
+        if (that.allFiles) {
+            return false;
+        }
         if (this.directory) {
             if (this.recursive) {
                 // make sure that.path is longer then path so
@@ -415,6 +443,10 @@
      * Checks two FilePermission objects for equality. Checks that <i>obj</i> is
      * a FilePermission, and has the same pathname and actions as this object.
      *
+     * @implNote More specifically, two pathnames are the same if and only if
+     * they have the same wildcard flag and their
+     * {@code npath} are equal. Or they are both {@literal "<<ALL FILES>>"}.
+     *
      * @param obj the object we are testing for equality with this object.
      * @return <code>true</code> if obj is a FilePermission, and has the same
      *          pathname and actions as this FilePermission object,
@@ -433,6 +465,7 @@
             return false;
         }
         return (this.mask == that.mask) &&
+            (this.allFiles == that.allFiles) &&
             this.cpath.equals(that.cpath) &&
             (this.directory == that.directory) &&
             (this.recursive == that.recursive);
diff --git a/src/share/classes/java/io/ObjectInputStream.java b/src/share/classes/java/io/ObjectInputStream.java
index 9d293c7..b16d53b 100644
--- a/src/share/classes/java/io/ObjectInputStream.java
+++ b/src/share/classes/java/io/ObjectInputStream.java
@@ -419,16 +419,50 @@
      * @throws  IOException Any of the usual Input/Output related exceptions.
      */
     public final Object readObject()
+        throws IOException, ClassNotFoundException {
+        return readObject(Object.class);
+    }
+
+    /**
+     * Reads a String and only a string.
+     *
+     * @return  the String read
+     * @throws  EOFException If end of file is reached.
+     * @throws  IOException If other I/O error has occurred.
+     */
+    private String readString() throws IOException {
+        try {
+            return (String) readObject(String.class);
+        } catch (ClassNotFoundException cnf) {
+            throw new IllegalStateException(cnf);
+        }
+    }
+
+    /**
+     * Internal method to read an object from the ObjectInputStream of the expected type.
+     * Called only from {@code readObject()} and {@code readString()}.
+     * Only {@code Object.class} and {@code String.class} are supported.
+     *
+     * @param type the type expected; either Object.class or String.class
+     * @return an object of the type
+     * @throws  IOException Any of the usual Input/Output related exceptions.
+     * @throws  ClassNotFoundException Class of a serialized object cannot be
+     *          found.
+     */
+    private final Object readObject(Class<?> type)
         throws IOException, ClassNotFoundException
     {
         if (enableOverride) {
             return readObjectOverride();
         }
 
+        if (! (type == Object.class || type == String.class))
+            throw new AssertionError("internal error");
+
         // if nested read, passHandle contains handle of enclosing object
         int outerHandle = passHandle;
         try {
-            Object obj = readObject0(false);
+            Object obj = readObject0(type, false);
             handles.markDependency(outerHandle, passHandle);
             ClassNotFoundException ex = handles.lookupException(passHandle);
             if (ex != null) {
@@ -518,7 +552,7 @@
         // if nested read, passHandle contains handle of enclosing object
         int outerHandle = passHandle;
         try {
-            Object obj = readObject0(true);
+            Object obj = readObject0(Object.class, true);
             handles.markDependency(outerHandle, passHandle);
             ClassNotFoundException ex = handles.lookupException(passHandle);
             if (ex != null) {
@@ -1517,8 +1551,10 @@
 
     /**
      * Underlying readObject implementation.
+     * @param type a type expected to be deserialized; non-null
+     * @param unshared true if the object can not be a reference to a shared object, otherwise false
      */
-    private Object readObject0(boolean unshared) throws IOException {
+    private Object readObject0(Class<?> type, boolean unshared) throws IOException {
         boolean oldMode = bin.getBlockDataMode();
         if (oldMode) {
             int remain = bin.currentBlockRemaining();
@@ -1550,13 +1586,20 @@
                     return readNull();
 
                 case TC_REFERENCE:
-                    return readHandle(unshared);
+                    // check the type of the existing object
+                    return type.cast(readHandle(unshared));
 
                 case TC_CLASS:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast a class to java.lang.String");
+                    }
                     return readClass(unshared);
 
                 case TC_CLASSDESC:
                 case TC_PROXYCLASSDESC:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast a class to java.lang.String");
+                    }
                     return readClassDesc(unshared);
 
                 case TC_STRING:
@@ -1564,15 +1607,27 @@
                     return checkResolve(readString(unshared));
 
                 case TC_ARRAY:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an array to java.lang.String");
+                    }
                     return checkResolve(readArray(unshared));
 
                 case TC_ENUM:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an enum to java.lang.String");
+                    }
                     return checkResolve(readEnum(unshared));
 
                 case TC_OBJECT:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an object to java.lang.String");
+                    }
                     return checkResolve(readOrdinaryObject(unshared));
 
                 case TC_EXCEPTION:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an exception to java.lang.String");
+                    }
                     IOException ex = readFatalException();
                     throw new WriteAbortedException("writing aborted", ex);
 
@@ -1947,7 +2002,7 @@
 
         if (ccl == null) {
             for (int i = 0; i < len; i++) {
-                readObject0(false);
+                readObject0(Object.class, false);
             }
         } else if (ccl.isPrimitive()) {
             if (ccl == Integer.TYPE) {
@@ -1972,7 +2027,7 @@
         } else {
             Object[] oa = (Object[]) array;
             for (int i = 0; i < len; i++) {
-                oa[i] = readObject0(false);
+                oa[i] = readObject0(Object.class, false);
                 handles.markDependency(arrayHandle, passHandle);
             }
         }
@@ -2250,7 +2305,7 @@
                     return;
 
                 default:
-                    readObject0(false);
+                    readObject0(Object.class, false);
                     break;
             }
         }
@@ -2284,7 +2339,7 @@
         int numPrimFields = fields.length - objVals.length;
         for (int i = 0; i < objVals.length; i++) {
             ObjectStreamField f = fields[numPrimFields + i];
-            objVals[i] = readObject0(f.isUnshared());
+            objVals[i] = readObject0(Object.class, f.isUnshared());
             if (f.getField() != null) {
                 handles.markDependency(objHandle, passHandle);
             }
@@ -2305,7 +2360,7 @@
             throw new InternalError();
         }
         clear();
-        return (IOException) readObject0(false);
+        return (IOException) readObject0(Object.class, false);
     }
 
     /**
@@ -2449,7 +2504,7 @@
             int numPrimFields = fields.length - objVals.length;
             for (int i = 0; i < objVals.length; i++) {
                 objVals[i] =
-                    readObject0(fields[numPrimFields + i].isUnshared());
+                    readObject0(Object.class, fields[numPrimFields + i].isUnshared());
                 objHandles[i] = passHandle;
             }
             passHandle = oldHandle;
@@ -3403,7 +3458,15 @@
          * utflen bytes.
          */
         private String readUTFBody(long utflen) throws IOException {
-            StringBuilder sbuf = new StringBuilder();
+            StringBuilder sbuf;
+            if (utflen > 0 && utflen < Integer.MAX_VALUE) {
+                // a reasonable initial capacity based on the UTF length
+                int initialCapacity = Math.min((int)utflen, 0xFFFF);
+                sbuf = new StringBuilder(initialCapacity);
+            } else {
+                sbuf = new StringBuilder();
+            }
+
             if (!blkmode) {
                 end = pos = 0;
             }
@@ -3918,5 +3981,6 @@
     }
     static {
         SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
+        SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString);
     }
 }
diff --git a/src/share/classes/java/lang/ClassLoader.java b/src/share/classes/java/lang/ClassLoader.java
index 2e98092..925fdac 100644
--- a/src/share/classes/java/lang/ClassLoader.java
+++ b/src/share/classes/java/lang/ClassLoader.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, Inc. 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
@@ -1467,6 +1468,17 @@
         }
     }
 
+    /*
+     * Initialize default paths for native libraries search.
+     * Must be done early as JDK may load libraries during bootstrap.
+     *
+     * @see java.lang.System#initPhase1
+     */
+    static void initLibraryPaths() {
+        usr_paths = initializePath("java.library.path");
+        sys_paths = initializePath("sun.boot.library.path");
+    }
+
     // Returns true if the specified class loader can be found in this class
     // loader's delegation chain.
     boolean isAncestor(ClassLoader cl) {
@@ -1809,10 +1821,9 @@
                             boolean isAbsolute) {
         ClassLoader loader =
             (fromClass == null) ? null : fromClass.getClassLoader();
-        if (sys_paths == null) {
-            usr_paths = initializePath("java.library.path");
-            sys_paths = initializePath("sun.boot.library.path");
-        }
+        assert sys_paths != null : "should be initialized at this point";
+        assert usr_paths != null : "should be initialized at this point";
+
         if (isAbsolute) {
             if (loadLibrary0(fromClass, new File(name))) {
                 return;
@@ -1902,13 +1913,14 @@
                          name +
                          " already loaded in another classloader");
                 }
-                /* If the library is being loaded (must be by the same thread,
-                 * because Runtime.load and Runtime.loadLibrary are
-                 * synchronous). The reason is can occur is that the JNI_OnLoad
-                 * function can cause another loadLibrary invocation.
+                /*
+                 * When a library is being loaded, JNI_OnLoad function can cause
+                 * another loadLibrary invocation that should succeed.
                  *
-                 * Thus we can use a static stack to hold the list of libraries
-                 * we are loading.
+                 * We use a static stack to hold the list of libraries we are
+                 * loading because this can happen only when called by the
+                 * same thread because Runtime.load and Runtime.loadLibrary
+                 * are synchronous.
                  *
                  * If there is a pending load operation for the library, we
                  * immediately return success; otherwise, we raise
diff --git a/src/share/classes/java/lang/Runtime.java b/src/share/classes/java/lang/Runtime.java
index 9e53dc9..5039059 100644
--- a/src/share/classes/java/lang/Runtime.java
+++ b/src/share/classes/java/lang/Runtime.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, Inc. 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
@@ -797,7 +798,7 @@
         load0(Reflection.getCallerClass(), filename);
     }
 
-    synchronized void load0(Class<?> fromClass, String filename) {
+    void load0(Class<?> fromClass, String filename) {
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkLink(filename);
@@ -858,14 +859,14 @@
         loadLibrary0(Reflection.getCallerClass(), libname);
     }
 
-    synchronized void loadLibrary0(Class<?> fromClass, String libname) {
+    void loadLibrary0(Class<?> fromClass, String libname) {
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkLink(libname);
         }
         if (libname.indexOf((int)File.separatorChar) != -1) {
             throw new UnsatisfiedLinkError(
-    "Directory separator should not appear in library name: " + libname);
+                "Directory separator should not appear in library name: " + libname);
         }
         ClassLoader.loadLibrary(fromClass, libname, false);
     }
diff --git a/src/share/classes/java/lang/System.java b/src/share/classes/java/lang/System.java
index b2747fa..c568f02 100644
--- a/src/share/classes/java/lang/System.java
+++ b/src/share/classes/java/lang/System.java
@@ -43,6 +43,8 @@
 import sun.security.util.SecurityConstants;
 import sun.reflect.annotation.AnnotationType;
 
+import jdk.internal.util.StaticProperty;
+
 /**
  * The <code>System</code> class contains several useful class fields
  * and methods. It cannot be instantiated.
@@ -1183,6 +1185,7 @@
 
 
         lineSeparator = props.getProperty("line.separator");
+        StaticProperty.jdkSerialFilter();   // Load StaticProperty to cache the property values
         sun.misc.Version.init();
 
         FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
@@ -1192,6 +1195,8 @@
         setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
         setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
 
+        ClassLoader.initLibraryPaths();
+
         // Load the zip library now in order to keep java.util.zip.ZipFile
         // from trying to use itself to load this library later.
         loadLibrary("zip");
diff --git a/src/share/classes/java/lang/reflect/Executable.java b/src/share/classes/java/lang/reflect/Executable.java
index 832b5cd..f5815da 100644
--- a/src/share/classes/java/lang/reflect/Executable.java
+++ b/src/share/classes/java/lang/reflect/Executable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -594,22 +594,29 @@
         return AnnotationParser.toArray(declaredAnnotations());
     }
 
-    private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
+    private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
 
-    private synchronized  Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
-        if (declaredAnnotations == null) {
-            Executable root = getRoot();
-            if (root != null) {
-                declaredAnnotations = root.declaredAnnotations();
-            } else {
-                declaredAnnotations = AnnotationParser.parseAnnotations(
-                    getAnnotationBytes(),
-                    sun.misc.SharedSecrets.getJavaLangAccess().
-                    getConstantPool(getDeclaringClass()),
-                    getDeclaringClass());
+    private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+        Map<Class<? extends Annotation>, Annotation> declAnnos;
+        if ((declAnnos = declaredAnnotations) == null) {
+            synchronized (this) {
+                if ((declAnnos = declaredAnnotations) == null) {
+                    Executable root = getRoot();
+                    if (root != null) {
+                        declAnnos = root.declaredAnnotations();
+                    } else {
+                        declAnnos = AnnotationParser.parseAnnotations(
+                                getAnnotationBytes(),
+                                sun.misc.SharedSecrets.getJavaLangAccess().
+                                        getConstantPool(getDeclaringClass()),
+                                getDeclaringClass()
+                        );
+                    }
+                    declaredAnnotations = declAnnos;
+                }
             }
         }
-        return declaredAnnotations;
+        return declAnnos;
     }
 
     /**
diff --git a/src/share/classes/java/lang/reflect/Field.java b/src/share/classes/java/lang/reflect/Field.java
index bb23b22..cb3cbf5 100644
--- a/src/share/classes/java/lang/reflect/Field.java
+++ b/src/share/classes/java/lang/reflect/Field.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -1139,21 +1139,28 @@
         return AnnotationParser.toArray(declaredAnnotations());
     }
 
-    private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
+    private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
 
-    private synchronized  Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
-        if (declaredAnnotations == null) {
-            Field root = this.root;
-            if (root != null) {
-                declaredAnnotations = root.declaredAnnotations();
-            } else {
-                declaredAnnotations = AnnotationParser.parseAnnotations(
-                        annotations,
-                        sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
-                        getDeclaringClass());
+    private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+        Map<Class<? extends Annotation>, Annotation> declAnnos;
+        if ((declAnnos = declaredAnnotations) == null) {
+            synchronized (this) {
+                if ((declAnnos = declaredAnnotations) == null) {
+                    Field root = this.root;
+                    if (root != null) {
+                        declAnnos = root.declaredAnnotations();
+                    } else {
+                        declAnnos = AnnotationParser.parseAnnotations(
+                                annotations,
+                                sun.misc.SharedSecrets.getJavaLangAccess()
+                                        .getConstantPool(getDeclaringClass()),
+                                getDeclaringClass());
+                    }
+                    declaredAnnotations = declAnnos;
+                }
             }
         }
-        return declaredAnnotations;
+        return declAnnos;
     }
 
     private native byte[] getTypeAnnotationBytes0();
diff --git a/src/share/classes/java/net/URL.java b/src/share/classes/java/net/URL.java
index bbe87b6..820733c 100644
--- a/src/share/classes/java/net/URL.java
+++ b/src/share/classes/java/net/URL.java
@@ -33,6 +33,7 @@
 import java.io.ObjectInputStream.GetField;
 import java.util.Hashtable;
 import java.util.StringTokenizer;
+import sun.misc.VM;
 import sun.net.util.IPAddressUtil;
 import sun.security.util.SecurityConstants;
 
@@ -1423,7 +1424,9 @@
     }
 
     boolean isBuiltinStreamHandler(URLStreamHandler handler) {
-       return isBuiltinStreamHandler(handler.getClass().getName());
+        Class<?> handlerClass = handler.getClass();
+        return isBuiltinStreamHandler(handlerClass.getName())
+                || VM.isSystemDomainLoader(handlerClass.getClassLoader());
     }
 
     private boolean isBuiltinStreamHandler(String handlerClassName) {
diff --git a/src/share/classes/java/nio/channels/SelectableChannel.java b/src/share/classes/java/nio/channels/SelectableChannel.java
index 997d5c5..c7d7596 100644
--- a/src/share/classes/java/nio/channels/SelectableChannel.java
+++ b/src/share/classes/java/nio/channels/SelectableChannel.java
@@ -121,7 +121,7 @@
     //   keySet, may be empty but is never null, typ. a tiny array
     //   boolean isRegistered, protected by key set
     //   regLock, lock object to prevent duplicate registrations
-    //   boolean isBlocking, protected by regLock
+    //   blocking mode, protected by regLock
 
     /**
      * Tells whether or not this channel is currently registered with any
diff --git a/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java b/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
index 0de212d..d5b3ce8 100644
--- a/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
+++ b/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -26,7 +26,14 @@
 package java.nio.channels.spi;
 
 import java.io.IOException;
-import java.nio.channels.*;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.IllegalSelectorException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
 
 
 /**
@@ -67,8 +74,8 @@
     // Lock for registration and configureBlocking operations
     private final Object regLock = new Object();
 
-    // Blocking mode, protected by regLock
-    boolean blocking = true;
+    // True when non-blocking, need regLock to change;
+    private volatile boolean nonBlocking;
 
     /**
      * Initializes a new instance of this class.
@@ -197,7 +204,7 @@
                 throw new ClosedChannelException();
             if ((ops & ~validOps()) != 0)
                 throw new IllegalArgumentException();
-            if (blocking)
+            if (isBlocking())
                 throw new IllegalBlockingModeException();
             SelectionKey k = findKey(sel);
             if (k != null) {
@@ -264,9 +271,7 @@
     // -- Blocking --
 
     public final boolean isBlocking() {
-        synchronized (regLock) {
-            return blocking;
-        }
+        return !nonBlocking;
     }
 
     public final Object blockingLock() {
@@ -287,12 +292,13 @@
         synchronized (regLock) {
             if (!isOpen())
                 throw new ClosedChannelException();
-            if (blocking == block)
-                return this;
-            if (block && haveValidKeys())
-                throw new IllegalBlockingModeException();
-            implConfigureBlocking(block);
-            blocking = block;
+            boolean blocking = !nonBlocking;
+            if (block != blocking) {
+                if (block && haveValidKeys())
+                    throw new IllegalBlockingModeException();
+                implConfigureBlocking(block);
+                nonBlocking = !block;
+            }
         }
         return this;
     }
diff --git a/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java b/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java
index c17eac6..3482b27 100644
--- a/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java
+++ b/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -29,6 +29,7 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.rmi.Remote;
+import java.rmi.RemoteException;
 import java.rmi.UnexpectedException;
 import java.rmi.activation.Activatable;
 import java.security.PrivilegedAction;
@@ -224,6 +225,13 @@
                 throw new IllegalArgumentException(
                     "proxy not Remote instance");
             }
+
+            // Verify that the method is declared on an interface that extends Remote
+            Class<?> decl = method.getDeclaringClass();
+            if (!Remote.class.isAssignableFrom(decl)) {
+                throw new RemoteException("Method is not Remote: " + decl + "::" + method);
+            }
+
             return ref.invoke((Remote) proxy, method, args,
                               getMethodHash(method));
         } catch (Exception e) {
diff --git a/src/share/classes/java/security/CodeSource.java b/src/share/classes/java/security/CodeSource.java
index eb78c1d..e2ca471 100644
--- a/src/share/classes/java/security/CodeSource.java
+++ b/src/share/classes/java/security/CodeSource.java
@@ -570,7 +570,7 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
+            byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
                 certList.add(cf.generateCertificate(bais));
diff --git a/src/share/classes/java/security/Key.java b/src/share/classes/java/security/Key.java
index c0c63d7..09542e3 100644
--- a/src/share/classes/java/security/Key.java
+++ b/src/share/classes/java/security/Key.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -63,7 +63,7 @@
  * </pre>
  *
  * For more information, see
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
  * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>.
  *
  * <LI>A Format
diff --git a/src/share/classes/java/security/UnresolvedPermission.java b/src/share/classes/java/security/UnresolvedPermission.java
index 2e8f5c7..c7eee55 100644
--- a/src/share/classes/java/security/UnresolvedPermission.java
+++ b/src/share/classes/java/security/UnresolvedPermission.java
@@ -590,7 +590,7 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
+            byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
                 certList.add(cf.generateCertificate(bais));
diff --git a/src/share/classes/java/security/cert/CRLReason.java b/src/share/classes/java/security/cert/CRLReason.java
index ac0b9e9..79d4729 100644
--- a/src/share/classes/java/security/cert/CRLReason.java
+++ b/src/share/classes/java/security/cert/CRLReason.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -27,8 +27,8 @@
 
 /**
  * The CRLReason enumeration specifies the reason that a certificate
- * is revoked, as defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
- * RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL
+ * is revoked, as defined in <a href="http://tools.ietf.org/html/rfc5280">
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL
  * Profile</a>.
  *
  * @author Sean Mullan
diff --git a/src/share/classes/java/security/cert/CertificateRevokedException.java b/src/share/classes/java/security/cert/CertificateRevokedException.java
index d478a79..98e4346 100644
--- a/src/share/classes/java/security/cert/CertificateRevokedException.java
+++ b/src/share/classes/java/security/cert/CertificateRevokedException.java
@@ -239,7 +239,7 @@
         for (int i = 0; i < size; i++) {
             String oid = (String) ois.readObject();
             boolean critical = ois.readBoolean();
-            byte[] extVal = IOUtils.readNBytes(ois, ois.readInt());
+            byte[] extVal = IOUtils.readExactlyNBytes(ois, ois.readInt());
             Extension ext = sun.security.x509.Extension.newExtension
                 (new ObjectIdentifier(oid), critical, extVal);
             extensions.put(oid, ext);
diff --git a/src/share/classes/java/security/cert/PKIXReason.java b/src/share/classes/java/security/cert/PKIXReason.java
index d58ded9..e9c4872 100644
--- a/src/share/classes/java/security/cert/PKIXReason.java
+++ b/src/share/classes/java/security/cert/PKIXReason.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -28,7 +28,7 @@
 /**
  * The {@code PKIXReason} enumerates the potential PKIX-specific reasons
  * that an X.509 certification path may be invalid according to the PKIX
- * (RFC 3280) standard. These reasons are in addition to those of the
+ * (RFC 5280) standard. These reasons are in addition to those of the
  * {@code CertPathValidatorException.BasicReason} enumeration.
  *
  * @since 1.7
diff --git a/src/share/classes/java/security/cert/TrustAnchor.java b/src/share/classes/java/security/cert/TrustAnchor.java
index c98bf81..e5be6a6 100644
--- a/src/share/classes/java/security/cert/TrustAnchor.java
+++ b/src/share/classes/java/security/cert/TrustAnchor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -78,7 +78,7 @@
      * The name constraints are specified as a byte array. This byte array
      * should contain the DER encoded form of the name constraints, as they
      * would appear in the NameConstraints structure defined in
-     * <a href="http://www.ietf.org/rfc/rfc3280">RFC 3280</a>
+     * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280</a>
      * and X.509. The ASN.1 definition of this structure appears below.
      *
      * <pre>{@code
@@ -140,7 +140,7 @@
      * <p>
      * The name constraints are specified as a byte array. This byte array
      * contains the DER encoded form of the name constraints, as they
-     * would appear in the NameConstraints structure defined in RFC 3280
+     * would appear in the NameConstraints structure defined in RFC 5280
      * and X.509. The ASN.1 notation for this structure is supplied in the
      * documentation for
      * {@link #TrustAnchor(X509Certificate, byte[])
@@ -179,7 +179,7 @@
      * <p>
      * The name constraints are specified as a byte array. This byte array
      * contains the DER encoded form of the name constraints, as they
-     * would appear in the NameConstraints structure defined in RFC 3280
+     * would appear in the NameConstraints structure defined in RFC 5280
      * and X.509. The ASN.1 notation for this structure is supplied in the
      * documentation for
      * {@link #TrustAnchor(X509Certificate, byte[])
@@ -294,7 +294,7 @@
      * <p>
      * The name constraints are returned as a byte array. This byte array
      * contains the DER encoded form of the name constraints, as they
-     * would appear in the NameConstraints structure defined in RFC 3280
+     * would appear in the NameConstraints structure defined in RFC 5280
      * and X.509. The ASN.1 notation for this structure is supplied in the
      * documentation for
      * {@link #TrustAnchor(X509Certificate, byte[])
diff --git a/src/share/classes/java/security/cert/X509CRL.java b/src/share/classes/java/security/cert/X509CRL.java
index 5ce8484..2133290 100644
--- a/src/share/classes/java/security/cert/X509CRL.java
+++ b/src/share/classes/java/security/cert/X509CRL.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -69,7 +69,7 @@
  * </pre>
  * <p>
  * More information can be found in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
  * Public Key Infrastructure Certificate and CRL Profile</a>.
  * <p>
  * The ASN.1 definition of {@code tbsCertList} is:
diff --git a/src/share/classes/java/security/cert/X509CRLSelector.java b/src/share/classes/java/security/cert/X509CRLSelector.java
index face5ff..cf2e6b4 100644
--- a/src/share/classes/java/security/cert/X509CRLSelector.java
+++ b/src/share/classes/java/security/cert/X509CRLSelector.java
@@ -52,7 +52,7 @@
  * {@link CertStore#getCRLs CertStore.getCRLs} or some similar
  * method.
  * <p>
- * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Please refer to <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
  * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>
  * for definitions of the X.509 CRL fields and extensions mentioned below.
  * <p>
diff --git a/src/share/classes/java/security/cert/X509CertSelector.java b/src/share/classes/java/security/cert/X509CertSelector.java
index 4a1ff7e..905e454 100644
--- a/src/share/classes/java/security/cert/X509CertSelector.java
+++ b/src/share/classes/java/security/cert/X509CertSelector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -65,7 +65,7 @@
  * number. Other unique combinations include the issuer, subject,
  * subjectKeyIdentifier and/or the subjectPublicKey criteria.
  * <p>
- * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Please refer to <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
  * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a> for
  * definitions of the X.509 certificate extensions mentioned below.
  * <p>
@@ -728,7 +728,7 @@
      * The name is provided in string format.
      * <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
      * names use the well-established string formats for those types (subject to
-     * the restrictions included in RFC 3280). IPv4 address names are
+     * the restrictions included in RFC 5280). IPv4 address names are
      * supplied using dotted quad notation. OID address names are represented
      * as a series of nonnegative integers separated by periods. And
      * directory names (distinguished names) are supplied in RFC 2253 format.
@@ -746,7 +746,7 @@
      * String form of some distinguished names.
      *
      * @param type the name type (0-8, as specified in
-     *             RFC 3280, section 4.2.1.7)
+     *             RFC 5280, section 4.2.1.6)
      * @param name the name in string form (not {@code null})
      * @throws IOException if a parsing error occurs
      */
@@ -770,7 +770,7 @@
      * <p>
      * The name is provided as a byte array. This byte array should contain
      * the DER encoded name, as it would appear in the GeneralName structure
-     * defined in RFC 3280 and X.509. The encoded byte array should only contain
+     * defined in RFC 5280 and X.509. The encoded byte array should only contain
      * the encoded value of the name, and should not include the tag associated
      * with the name in the GeneralName structure. The ASN.1 definition of this
      * structure appears below.
@@ -806,7 +806,7 @@
      * must contain the specified subjectAlternativeName.
      *
      * @param type the name type (0-8, as specified in
-     *             RFC 3280, section 4.2.1.7)
+     *             RFC 5280, section 4.2.1.6)
      * @param name the name in string or byte array form
      * @throws IOException if a parsing error occurs
      */
@@ -995,7 +995,7 @@
      * <p>
      * The name constraints are specified as a byte array. This byte array
      * should contain the DER encoded form of the name constraints, as they
-     * would appear in the NameConstraints structure defined in RFC 3280
+     * would appear in the NameConstraints structure defined in RFC 5280
      * and X.509. The ASN.1 definition of this structure appears below.
      *
      * <pre>{@code
@@ -1197,7 +1197,7 @@
      * <p>
      * The name is provided in string format. RFC 822, DNS, and URI names
      * use the well-established string formats for those types (subject to
-     * the restrictions included in RFC 3280). IPv4 address names are
+     * the restrictions included in RFC 5280). IPv4 address names are
      * supplied using dotted quad notation. OID address names are represented
      * as a series of nonnegative integers separated by periods. And
      * directory names (distinguished names) are supplied in RFC 2253 format.
@@ -1214,7 +1214,7 @@
      * String form of some distinguished names.
      *
      * @param type the name type (0-8, as specified in
-     *             RFC 3280, section 4.2.1.7)
+     *             RFC 5280, section 4.2.1.6)
      * @param name the name in string form
      * @throws IOException if a parsing error occurs
      */
@@ -1234,7 +1234,7 @@
      * <p>
      * The name is provided as a byte array. This byte array should contain
      * the DER encoded name, as it would appear in the GeneralName structure
-     * defined in RFC 3280 and X.509. The ASN.1 definition of this structure
+     * defined in RFC 5280 and X.509. The ASN.1 definition of this structure
      * appears in the documentation for
      * {@link #addSubjectAlternativeName(int type, byte [] name)
      * addSubjectAlternativeName(int type, byte [] name)}.
@@ -1243,7 +1243,7 @@
      * subsequent modifications.
      *
      * @param type the name type (0-8, as specified in
-     *             RFC 3280, section 4.2.1.7)
+     *             RFC 5280, section 4.2.1.6)
      * @param name a byte array containing the name in ASN.1 DER encoded form
      * @throws IOException if a parsing error occurs
      */
@@ -1258,7 +1258,7 @@
      * the specified pathToName.
      *
      * @param type the name type (0-8, as specified in
-     *             RFC 3280, section 4.2.1.7)
+     *             RFC 5280, section 4.2.1.6)
      * @param name the name in string or byte array form
      * @throws IOException if an encoding error occurs (incorrect form for DN)
      */
@@ -1715,7 +1715,7 @@
      * <p>
      * The name constraints are returned as a byte array. This byte array
      * contains the DER encoded form of the name constraints, as they
-     * would appear in the NameConstraints structure defined in RFC 3280
+     * would appear in the NameConstraints structure defined in RFC 5280
      * and X.509. The ASN.1 notation for this structure is supplied in the
      * documentation for
      * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
@@ -2115,8 +2115,11 @@
             if (certSubjectKeyID == null ||
                     !Arrays.equals(subjectKeyID, certSubjectKeyID)) {
                 if (debug != null) {
-                    debug.println("X509CertSelector.match: "
-                        + "subject key IDs don't match");
+                    debug.println("X509CertSelector.match: subject key IDs " +
+                        "don't match\nX509CertSelector.match: subjectKeyID: " +
+                        Arrays.toString(subjectKeyID) +
+                        "\nX509CertSelector.match: certSubjectKeyID: " +
+                        Arrays.toString(certSubjectKeyID));
                 }
                 return false;
             }
diff --git a/src/share/classes/java/security/cert/X509Certificate.java b/src/share/classes/java/security/cert/X509Certificate.java
index 0aba5da..174d6a7 100644
--- a/src/share/classes/java/security/cert/X509Certificate.java
+++ b/src/share/classes/java/security/cert/X509Certificate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -63,7 +63,7 @@
  * CA such as a "root" CA.
  * <p>
  * More information can be found in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
  * Public Key Infrastructure Certificate and CRL Profile</a>.
  * <p>
  * The ASN.1 definition of {@code tbsCertificate} is:
@@ -408,7 +408,7 @@
      * Gets the {@code issuerUniqueID} value from the certificate.
      * The issuer unique identifier is present in the certificate
      * to handle the possibility of reuse of issuer names over time.
-     * RFC 3280 recommends that names not be reused and that
+     * RFC 5280 recommends that names not be reused and that
      * conforming certificates not make use of unique identifiers.
      * Applications conforming to that profile should be capable of
      * parsing unique identifiers and making comparisons.
@@ -459,7 +459,7 @@
      *     encipherOnly            (7),
      *     decipherOnly            (8) }
      * </pre>
-     * RFC 3280 recommends that when used, this be marked
+     * RFC 5280 recommends that when used, this be marked
      * as a critical extension.
      *
      * @return the KeyUsage extension of this certificate, represented as
@@ -572,7 +572,7 @@
      * <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
      * names are returned as {@code String}s,
      * using the well-established string formats for those types (subject to
-     * the restrictions included in RFC 3280). IPv4 address names are
+     * the restrictions included in RFC 5280). IPv4 address names are
      * returned using dotted quad notation. IPv6 address names are returned
      * in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values
      * representing the eight 16-bit pieces of the address. OID names are
diff --git a/src/share/classes/java/util/Formattable.java b/src/share/classes/java/util/Formattable.java
index f7e1e50..fa87e9c 100644
--- a/src/share/classes/java/util/Formattable.java
+++ b/src/share/classes/java/util/Formattable.java
@@ -36,14 +36,14 @@
  * For example, the following class prints out different representations of a
  * stock's name depending on the flags and length constraints:
  *
- * {@code
+ * <pre> {@code
  *   import java.nio.CharBuffer;
  *   import java.util.Formatter;
  *   import java.util.Formattable;
  *   import java.util.Locale;
  *   import static java.util.FormattableFlags.*;
  *
- *  ...
+ *   ...
  *
  *   public class StockName implements Formattable {
  *       private String symbol, companyName, frenchCompanyName;
@@ -89,12 +89,12 @@
  *           return String.format("%s - %s", symbol, companyName);
  *       }
  *   }
- * }
+ * }</pre>
  *
  * <p> When used in conjunction with the {@link java.util.Formatter}, the above
  * class produces the following output for various format strings.
  *
- * {@code
+ * <pre> {@code
  *   Formatter fmt = new Formatter();
  *   StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
  *                                "Fruit Titanesque, Inc.");
@@ -104,7 +104,7 @@
  *   fmt.format("%-10.8s", sn);              //   -> "HUGE      "
  *   fmt.format("%.12s", sn);                //   -> "Huge Fruit,*"
  *   fmt.format(Locale.FRANCE, "%25s", sn);  //   -> "   Fruit Titanesque, Inc."
- * }
+ * }</pre>
  *
  * <p> Formattables are not necessarily safe for multithreaded access.  Thread
  * safety is optional and may be enforced by classes that extend and implement
diff --git a/src/share/classes/java/util/jar/JarFile.java b/src/share/classes/java/util/jar/JarFile.java
index 940dfb6..dd6d1a4 100644
--- a/src/share/classes/java/util/jar/JarFile.java
+++ b/src/share/classes/java/util/jar/JarFile.java
@@ -422,7 +422,12 @@
      */
     private byte[] getBytes(ZipEntry ze) throws IOException {
         try (InputStream is = super.getInputStream(ze)) {
-            return IOUtils.readFully(is, (int)ze.getSize(), true);
+            int len = (int)ze.getSize();
+            byte[] b = IOUtils.readAllBytes(is);
+            if (len != -1 && b.length != len)
+                throw new EOFException("Expected:" + len + ", read:" + b.length);
+
+            return b;
         }
     }
 
diff --git a/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java b/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
index 71cc0aa..ff39983 100644
--- a/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
+++ b/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
@@ -33,6 +33,22 @@
             KeyTab ktab) {
         return ktab.takeSnapshot();
     }
+
+    public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t) {
+        return t.clientAlias;
+    }
+
+    public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a) {
+        t.clientAlias = a;
+    }
+
+    public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t) {
+        return t.serverAlias;
+    }
+
+    public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a) {
+        t.serverAlias = a;
+    }
     public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) {
         return t.proxy;
     }
diff --git a/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java b/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
index 308b619..ef767f0 100644
--- a/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
+++ b/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -80,6 +80,11 @@
 
     public static final int KRB_NT_UID = 5;
 
+    /**
+     * Enterprise name (alias)
+     */
+    static final int KRB_NT_ENTERPRISE = 10;
+
     private transient String fullName;
 
     private transient String realm;
diff --git a/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java b/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java
index 0327f04..3f29d9b 100644
--- a/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java
+++ b/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java
@@ -194,6 +194,10 @@
 
     private InetAddress[] clientAddresses;
 
+    transient KerberosPrincipal clientAlias = null;
+
+    transient KerberosPrincipal serverAlias = null;
+
     /**
      * Evidence ticket if proxy_impersonator. This field can be accessed
      * by KerberosSecrets. It's serialized.
@@ -308,11 +312,7 @@
         } else
            this.flags = new boolean[NUM_FLAGS];
 
-        if (this.flags[RENEWABLE_TICKET_FLAG]) {
-           if (renewTill == null)
-                throw new IllegalArgumentException("The renewable period "
-                       + "end time cannot be null for renewable tickets.");
-
+        if (this.flags[RENEWABLE_TICKET_FLAG] && renewTill != null) {
            this.renewTill = new Date(renewTill.getTime());
         }
 
@@ -553,6 +553,11 @@
         if (!isRenewable())
             throw new RefreshFailedException("This ticket is not renewable");
 
+        if (getRenewTill() == null) {
+            // Renewable ticket without renew-till. Illegal and ignored.
+            return;
+        }
+
         if (System.currentTimeMillis() > getRenewTill().getTime())
             throw new RefreshFailedException("This ticket is past "
                                              + "its last renewal time.");
@@ -562,7 +567,11 @@
         try {
             krb5Creds = new sun.security.krb5.Credentials(asn1Encoding,
                                                     client.toString(),
+                                                    (clientAlias != null ?
+                                                            clientAlias.getName() : null),
                                                     server.toString(),
+                                                    (serverAlias != null ?
+                                                            serverAlias.getName() : null),
                                                     sessionKey.getEncoded(),
                                                     sessionKey.getKeyType(),
                                                     flags,
diff --git a/src/share/classes/javax/security/auth/x500/X500Principal.java b/src/share/classes/javax/security/auth/x500/X500Principal.java
index 77292b0..2236661 100644
--- a/src/share/classes/javax/security/auth/x500/X500Principal.java
+++ b/src/share/classes/javax/security/auth/x500/X500Principal.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -41,13 +41,13 @@
  * of the distinguished name, or by using the ASN.1 DER encoded byte
  * representation of the distinguished name.  The current specification
  * for the string representation of a distinguished name is defined in
- * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253: Lightweight
+ * <a href="http://tools.ietf.org/html/rfc2253">RFC 2253: Lightweight
  * Directory Access Protocol (v3): UTF-8 String Representation of
  * Distinguished Names</a>. This class, however, accepts string formats from
- * both RFC 2253 and <a href="http://www.ietf.org/rfc/rfc1779.txt">RFC 1779:
+ * both RFC 2253 and <a href="http://tools.ietf.org/html/rfc1779">RFC 1779:
  * A String Representation of Distinguished Names</a>, and also recognizes
  * attribute type keywords whose OIDs (Object Identifiers) are defined in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
  * Public Key Infrastructure Certificate and CRL Profile</a>.
  *
  * <p> The string representation for this {@code X500Principal}
@@ -108,7 +108,7 @@
      * (and listed in {@link #getName(String format) getName(String format)}),
      * as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
      * GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object
-     * Identifiers (OIDs) are defined in RFC 3280 and its successor.
+     * Identifiers (OIDs) are defined in RFC 5280.
      * Any other attribute type must be specified as an OID.
      *
      * <p>This implementation enforces a more restrictive OID syntax than
@@ -456,7 +456,7 @@
      * (obtained via the {@code getName(X500Principal.CANONICAL)} method)
      * of this object and <i>o</i> are equal.
      *
-     * <p> This implementation is compliant with the requirements of RFC 3280.
+     * <p> This implementation is compliant with the requirements of RFC 5280.
      *
      * @param o Object to be compared for equality with this
      *          {@code X500Principal}
diff --git a/src/share/classes/javax/security/auth/x500/package-info.java b/src/share/classes/javax/security/auth/x500/package-info.java
index 12f8a53..1e9ca1a 100644
--- a/src/share/classes/javax/security/auth/x500/package-info.java
+++ b/src/share/classes/javax/security/auth/x500/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -31,15 +31,15 @@
  * <h2>Package Specification</h2>
  *
  * <ul>
- *   <li><a href="http://www.ietf.org/rfc/rfc1779.txt">
+ *   <li><a href="http://tools.ietf.org/html/rfc1779">
  *     RFC 1779: A String Representation of Distinguished Names</a></li>
- *   <li><a href="http://www.ietf.org/rfc/rfc2253.txt">
+ *   <li><a href="http://tools.ietf.org/html/rfc2253">
  *     RFC 2253: Lightweight Directory Access Protocol (v3):
  *     UTF-8 String Representation of Distinguished Names</a></li>
- *   <li><a href="http://www.ietf.org/rfc/rfc3280.txt">
- *     RFC 3280: Internet X.509 Public Key Infrastructure
+ *   <li><a href="http://tools.ietf.org/html/rfc5280">
+ *     RFC 5280: Internet X.509 Public Key Infrastructure
  *     Certificate and Certificate Revocation List (CRL) Profile</a></li>
- *   <li><a href="http://www.ietf.org/rfc/rfc4512.txt">
+ *   <li><a href="http://tools.ietf.org/html/rfc4512">
  *     RFC 4512: Lightweight Directory Access Protocol (LDAP):
  *     Directory Information Models</a></li>
  * </ul>
diff --git a/src/share/classes/javax/swing/ToolTipManager.java b/src/share/classes/javax/swing/ToolTipManager.java
index 6a3954f..ee6992b 100644
--- a/src/share/classes/javax/swing/ToolTipManager.java
+++ b/src/share/classes/javax/swing/ToolTipManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -28,6 +28,8 @@
 
 import java.awt.event.*;
 import java.awt.*;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
 
 /**
  * Manages all the <code>ToolTips</code> in the system.
@@ -409,8 +411,14 @@
         component.addMouseListener(this);
         component.removeMouseMotionListener(moveBeforeEnterListener);
         component.addMouseMotionListener(moveBeforeEnterListener);
-        component.removeKeyListener(accessibilityKeyListener);
-        component.addKeyListener(accessibilityKeyListener);
+        // use MenuKeyListener for menu items/elements
+        if (component instanceof JMenuItem) {
+            ((JMenuItem) component).removeMenuKeyListener((MenuKeyListener) accessibilityKeyListener);
+            ((JMenuItem) component).addMenuKeyListener((MenuKeyListener) accessibilityKeyListener);
+        } else {
+            component.removeKeyListener(accessibilityKeyListener);
+            component.addKeyListener(accessibilityKeyListener);
+        }
     }
 
     /**
@@ -421,7 +429,11 @@
     public void unregisterComponent(JComponent component) {
         component.removeMouseListener(this);
         component.removeMouseMotionListener(moveBeforeEnterListener);
-        component.removeKeyListener(accessibilityKeyListener);
+        if (component instanceof JMenuItem) {
+            ((JMenuItem) component).removeMenuKeyListener((MenuKeyListener) accessibilityKeyListener);
+        } else {
+            component.removeKeyListener(accessibilityKeyListener);
+        }
     }
 
     // implements java.awt.event.MouseListener
@@ -841,7 +853,7 @@
      * Post Tip: Ctrl+F1
      * Unpost Tip: Esc and Ctrl+F1
      */
-    private class AccessibilityKeyListener extends KeyAdapter {
+    private class AccessibilityKeyListener extends KeyAdapter implements MenuKeyListener {
         public void keyPressed(KeyEvent e) {
             if (!e.isConsumed()) {
                 JComponent source = (JComponent) e.getComponent();
@@ -858,5 +870,32 @@
                 }
             }
         }
+
+        @Override
+        public void menuKeyTyped(MenuKeyEvent e) {}
+
+        @Override
+        public void menuKeyPressed(MenuKeyEvent e) {
+            if (postTip.equals(KeyStroke.getKeyStrokeForEvent(e))) {
+                // get element for the event
+                MenuElement path[] = e.getPath();
+                MenuElement element = path[path.length - 1];
+
+                // retrieve currently highlighted element
+                MenuSelectionManager msm = e.getMenuSelectionManager();
+                MenuElement selectedPath[] = msm.getSelectedPath();
+                MenuElement selectedElement = selectedPath[selectedPath.length - 1];
+
+                if (element.equals(selectedElement)) {
+                    // show/hide tooltip message
+                    JComponent source = (JComponent) element.getComponent();
+                    ToolTipManager.this.show(source);
+                    e.consume();
+                }
+            }
+        }
+
+        @Override
+        public void menuKeyReleased(MenuKeyEvent e) {}
     }
 }
diff --git a/src/share/classes/jdk/internal/util/StaticProperty.java b/src/share/classes/jdk/internal/util/StaticProperty.java
new file mode 100644
index 0000000..1ac81df
--- /dev/null
+++ b/src/share/classes/jdk/internal/util/StaticProperty.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util;
+
+/**
+ * System Property access for internal use only.
+ * Read-only access to System property values initialized during Phase 1
+ * are cached.  Setting, clearing, or modifying the value using
+ * {@link System#setProperty) or {@link System#getProperties()} is ignored.
+ * <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
+ * in these access methods. The caller of these methods should take care to ensure
+ * that the returned property is not made accessible to untrusted code.</strong>
+ */
+public final class StaticProperty {
+
+    // The class static initialization is triggered to initialize these final
+    // fields during init Phase 1 and before a security manager is set.
+    private static final String JDK_SERIAL_FILTER = System.getProperty("jdk.serialFilter");
+
+    private StaticProperty() {}
+
+    /**
+     *
+     * Return the {@code jdk.serialFilter} system property.
+     *
+     * <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
+     * in this method. The caller of this method should take care to ensure
+     * that the returned property is not made accessible to untrusted code.</strong>
+     *
+     * @return the {@code user.name} system property
+     */
+    public static String jdkSerialFilter() {
+        return JDK_SERIAL_FILTER;
+    }
+}
diff --git a/src/share/classes/sun/applet/AppletClassLoader.java b/src/share/classes/sun/applet/AppletClassLoader.java
index f732ad2..1fcd158 100644
--- a/src/share/classes/sun/applet/AppletClassLoader.java
+++ b/src/share/classes/sun/applet/AppletClassLoader.java
@@ -33,6 +33,7 @@
 import java.net.MalformedURLException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.io.EOFException;
 import java.io.File;
 import java.io.FilePermission;
 import java.io.IOException;
@@ -333,7 +334,9 @@
 
         byte[] b;
         try {
-            b = IOUtils.readFully(in, len, true);
+            b = IOUtils.readAllBytes(in);
+            if (len != -1 && b.length != len)
+                throw new EOFException("Expected:" + len + ", read:" + b.length);
         } finally {
             in.close();
         }
diff --git a/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java b/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java
index e70484d..c51ee7d 100644
--- a/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java
+++ b/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java
@@ -27,6 +27,7 @@
 
 import java.awt.AlphaComposite;
 import java.awt.Composite;
+import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsEnvironment;
 import java.awt.Rectangle;
 import java.awt.Transparency;
@@ -590,16 +591,16 @@
      * (referenced by the pData parameter).  This method is invoked from
      * the native Dispose() method from the Disposer thread when the
      * Java-level OGLSurfaceData object is about to go away.  Note that we
-     * also pass a reference to the native GLX/WGLGraphicsConfigInfo
-     * (pConfigInfo) for the purposes of making a context current.
+     * also pass a reference to the OGLGraphicsConfig
+     * for the purposes of making a context current.
      */
-    static void dispose(long pData, long pConfigInfo) {
+    static void dispose(long pData, OGLGraphicsConfig gc) {
         OGLRenderQueue rq = OGLRenderQueue.getInstance();
         rq.lock();
         try {
             // make sure we have a current context before
             // disposing the native resources (e.g. texture object)
-            OGLContext.setScratchSurface(pConfigInfo);
+            OGLContext.setScratchSurface(gc);
 
             RenderBuffer buf = rq.getBuffer();
             rq.ensureCapacityAndAlignment(12, 4);
diff --git a/src/share/classes/sun/misc/IOUtils.java b/src/share/classes/sun/misc/IOUtils.java
index 67079b9..5e6c79c 100644
--- a/src/share/classes/sun/misc/IOUtils.java
+++ b/src/share/classes/sun/misc/IOUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -32,67 +32,282 @@
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
+
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
 
 public class IOUtils {
 
-    /**
-     * Read up to {@code length} of bytes from {@code in}
-     * until EOF is detected.
-     * @param is input stream, must not be null
-     * @param length number of bytes to read, -1 or Integer.MAX_VALUE means
-     *        read as much as possible
-     * @param readAll if true, an EOFException will be thrown if not enough
-     *        bytes are read. Ignored when length is -1 or Integer.MAX_VALUE
-     * @return bytes read
-     * @throws IOException Any IO error or a premature EOF is detected
-     */
-    public static byte[] readFully(InputStream is, int length, boolean readAll)
-            throws IOException {
-        byte[] output = {};
-        if (length == -1) length = Integer.MAX_VALUE;
-        int pos = 0;
-        while (pos < length) {
-            int bytesToRead;
-            if (pos >= output.length) { // Only expand when there's no room
-                bytesToRead = Math.min(length - pos, output.length + 1024);
-                if (output.length < pos + bytesToRead) {
-                    output = Arrays.copyOf(output, pos + bytesToRead);
-                }
-            } else {
-                bytesToRead = output.length - pos;
-            }
-            int cc = is.read(output, pos, bytesToRead);
-            if (cc < 0) {
-                if (readAll && length != Integer.MAX_VALUE) {
-                    throw new EOFException("Detect premature EOF");
-                } else {
-                    if (output.length != pos) {
-                        output = Arrays.copyOf(output, pos);
-                    }
-                    break;
-                }
-            }
-            pos += cc;
-        }
-        return output;
-    }
+    private static final int DEFAULT_BUFFER_SIZE = 8192;
 
     /**
-     * Read {@code length} of bytes from {@code in}. An exception is
-     * thrown if there are not enough bytes in the stream.
+     * The maximum size of array to allocate.
+     * Some VMs reserve some header words in an array.
+     * Attempts to allocate larger arrays may result in
+     * OutOfMemoryError: Requested array size exceeds VM limit
+     */
+    private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
+
+    /**
+     * Read exactly {@code length} of bytes from {@code in}.
+     *
+     * <p> Note that this method is safe to be called with unknown large
+     * {@code length} argument. The memory used is proportional to the
+     * actual bytes available. An exception is thrown if there are not
+     * enough bytes in the stream.
      *
      * @param is input stream, must not be null
-     * @param length number of bytes to read, must not be negative
+     * @param length number of bytes to read
      * @return bytes read
-     * @throws IOException if any IO error or a premature EOF is detected, or
-     *      if {@code length} is negative since this length is usually also
-     *      read from {@code is}.
+     * @throws EOFException if there are not enough bytes in the stream
+     * @throws IOException if an I/O error occurs or {@code length} is negative
+     * @throws OutOfMemoryError if an array of the required size cannot be
+     *         allocated.
      */
-    public static byte[] readNBytes(InputStream is, int length) throws IOException {
+    public static byte[] readExactlyNBytes(InputStream is, int length)
+            throws IOException {
         if (length < 0) {
             throw new IOException("length cannot be negative: " + length);
         }
-        return readFully(is, length, true);
+        byte[] data = readNBytes(is, length);
+        if (data.length < length) {
+            throw new EOFException();
+        }
+        return data;
+    }
+
+    /**
+     * Reads all remaining bytes from the input stream. This method blocks until
+     * all remaining bytes have been read and end of stream is detected, or an
+     * exception is thrown. This method does not close the input stream.
+     *
+     * <p> When this stream reaches end of stream, further invocations of this
+     * method will return an empty byte array.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read all bytes into a byte array. It is not intended for
+     * reading input streams with large amounts of data.
+     *
+     * <p> The behavior for the case where the input stream is <i>asynchronously
+     * closed</i>, or the thread interrupted during the read, is highly input
+     * stream specific, and therefore not specified.
+     *
+     * <p> If an I/O error occurs reading from the input stream, then it may do
+     * so after some, but not all, bytes have been read. Consequently the input
+     * stream may not be at end of stream and may be in an inconsistent state.
+     * It is strongly recommended that the stream be promptly closed if an I/O
+     * error occurs.
+     *
+     * @implSpec
+     * This method invokes {@link #readNBytes(int)} with a length of
+     * {@link Integer#MAX_VALUE}.
+     *
+     * @param is input stream, must not be null
+     * @return a byte array containing the bytes read from this input stream
+     * @throws IOException if an I/O error occurs
+     * @throws OutOfMemoryError if an array of the required size cannot be
+     *         allocated.
+     *
+     * @since 1.9
+     */
+    public static byte[] readAllBytes(InputStream is) throws IOException {
+        return readNBytes(is, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Reads up to a specified number of bytes from the input stream. This
+     * method blocks until the requested number of bytes have been read, end
+     * of stream is detected, or an exception is thrown. This method does not
+     * close the input stream.
+     *
+     * <p> The length of the returned array equals the number of bytes read
+     * from the stream. If {@code len} is zero, then no bytes are read and
+     * an empty byte array is returned. Otherwise, up to {@code len} bytes
+     * are read from the stream. Fewer than {@code len} bytes may be read if
+     * end of stream is encountered.
+     *
+     * <p> When this stream reaches end of stream, further invocations of this
+     * method will return an empty byte array.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read the specified number of bytes into a byte array. The
+     * total amount of memory allocated by this method is proportional to the
+     * number of bytes read from the stream which is bounded by {@code len}.
+     * Therefore, the method may be safely called with very large values of
+     * {@code len} provided sufficient memory is available.
+     *
+     * <p> The behavior for the case where the input stream is <i>asynchronously
+     * closed</i>, or the thread interrupted during the read, is highly input
+     * stream specific, and therefore not specified.
+     *
+     * <p> If an I/O error occurs reading from the input stream, then it may do
+     * so after some, but not all, bytes have been read. Consequently the input
+     * stream may not be at end of stream and may be in an inconsistent state.
+     * It is strongly recommended that the stream be promptly closed if an I/O
+     * error occurs.
+     *
+     * @implNote
+     * The number of bytes allocated to read data from this stream and return
+     * the result is bounded by {@code 2*(long)len}, inclusive.
+     *
+     * @param is input stream, must not be null
+     * @param len the maximum number of bytes to read
+     * @return a byte array containing the bytes read from this input stream
+     * @throws IllegalArgumentException if {@code length} is negative
+     * @throws IOException if an I/O error occurs
+     * @throws OutOfMemoryError if an array of the required size cannot be
+     *         allocated.
+     *
+     * @since 11
+     */
+    public static byte[] readNBytes(InputStream is, int len) throws IOException {
+        if (len < 0) {
+            throw new IllegalArgumentException("len < 0");
+        }
+
+        List<byte[]> bufs = null;
+        byte[] result = null;
+        int total = 0;
+        int remaining = len;
+        int n;
+        do {
+            byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
+            int nread = 0;
+
+            // read to EOF which may read more or less than buffer size
+            while ((n = is.read(buf, nread,
+                    Math.min(buf.length - nread, remaining))) > 0) {
+                nread += n;
+                remaining -= n;
+            }
+
+            if (nread > 0) {
+                if (MAX_BUFFER_SIZE - total < nread) {
+                    throw new OutOfMemoryError("Required array size too large");
+                }
+                total += nread;
+                if (result == null) {
+                    result = buf;
+                } else {
+                    if (bufs == null) {
+                        bufs = new ArrayList<>();
+                        bufs.add(result);
+                    }
+                    bufs.add(buf);
+                }
+            }
+            // if the last call to read returned -1 or the number of bytes
+            // requested have been read then break
+        } while (n >= 0 && remaining > 0);
+
+        if (bufs == null) {
+            if (result == null) {
+                return new byte[0];
+            }
+            return result.length == total ?
+                result : Arrays.copyOf(result, total);
+        }
+
+        result = new byte[total];
+        int offset = 0;
+        remaining = total;
+        for (byte[] b : bufs) {
+            int count = Math.min(b.length, remaining);
+            System.arraycopy(b, 0, result, offset, count);
+            offset += count;
+            remaining -= count;
+        }
+
+        return result;
+    }
+
+    /**
+     * Reads the requested number of bytes from the input stream into the given
+     * byte array. This method blocks until {@code len} bytes of input data have
+     * been read, end of stream is detected, or an exception is thrown. The
+     * number of bytes actually read, possibly zero, is returned. This method
+     * does not close the input stream.
+     *
+     * <p> In the case where end of stream is reached before {@code len} bytes
+     * have been read, then the actual number of bytes read will be returned.
+     * When this stream reaches end of stream, further invocations of this
+     * method will return zero.
+     *
+     * <p> If {@code len} is zero, then no bytes are read and {@code 0} is
+     * returned; otherwise, there is an attempt to read up to {@code len} bytes.
+     *
+     * <p> The first byte read is stored into element {@code b[off]}, the next
+     * one in to {@code b[off+1]}, and so on. The number of bytes read is, at
+     * most, equal to {@code len}. Let <i>k</i> be the number of bytes actually
+     * read; these bytes will be stored in elements {@code b[off]} through
+     * {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>
+     * {@code ]} through {@code b[off+len-1]} unaffected.
+     *
+     * <p> The behavior for the case where the input stream is <i>asynchronously
+     * closed</i>, or the thread interrupted during the read, is highly input
+     * stream specific, and therefore not specified.
+     *
+     * <p> If an I/O error occurs reading from the input stream, then it may do
+     * so after some, but not all, bytes of {@code b} have been updated with
+     * data from the input stream. Consequently the input stream and {@code b}
+     * may be in an inconsistent state. It is strongly recommended that the
+     * stream be promptly closed if an I/O error occurs.
+     *
+     * @param  is input stream, must not be null
+     * @param  b the byte array into which the data is read
+     * @param  off the start offset in {@code b} at which the data is written
+     * @param  len the maximum number of bytes to read
+     * @return the actual number of bytes read into the buffer
+     * @throws IOException if an I/O error occurs
+     * @throws NullPointerException if {@code b} is {@code null}
+     * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}
+     *         is negative, or {@code len} is greater than {@code b.length - off}
+     *
+     * @since 1.9
+     */
+    public static int readNBytes(InputStream is, byte[] b, int off, int len) throws IOException {
+        Objects.requireNonNull(b);
+        if (off < 0 || len < 0 || len > b.length - off)
+            throw new IndexOutOfBoundsException();
+        int n = 0;
+        while (n < len) {
+            int count = is.read(b, off + n, len - n);
+            if (count < 0)
+                break;
+            n += count;
+        }
+        return n;
+    }
+
+    /**
+     * Compatibility wrapper for third party users of
+     * {@code sun.misc.IOUtils.readFully} following its
+     * removal in JDK-8231139.
+     *
+     * Read up to {@code length} of bytes from {@code in}
+     * until EOF is detected.
+     *
+     * @param is input stream, must not be null
+     * @param length number of bytes to read
+     * @param readAll if true, an EOFException will be thrown if not enough
+     *        bytes are read.
+     * @return bytes read
+     * @throws EOFException if there are not enough bytes in the stream
+     * @throws IOException if an I/O error occurs or {@code length} is negative
+     * @throws OutOfMemoryError if an array of the required size cannot be
+     *         allocated.
+     */
+    public static byte[] readFully(InputStream is, int length, boolean readAll)
+             throws IOException {
+        if (length < 0) {
+            throw new IOException("length cannot be negative: " + length);
+        }
+        if (readAll) {
+            return readExactlyNBytes(is, length);
+        } else {
+            return readNBytes(is, length);
+        }
     }
 }
diff --git a/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java b/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java
new file mode 100644
index 0000000..ed7a6c3
--- /dev/null
+++ b/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * Interface to specify methods for accessing {@code ObjectInputStream}.
+ */
+@FunctionalInterface
+public interface JavaObjectInputStreamReadString {
+    String readString(ObjectInputStream ois) throws IOException;
+}
+
diff --git a/src/share/classes/sun/misc/ObjectInputFilter.java b/src/share/classes/sun/misc/ObjectInputFilter.java
index 9b2c689..af21c74 100644
--- a/src/share/classes/sun/misc/ObjectInputFilter.java
+++ b/src/share/classes/sun/misc/ObjectInputFilter.java
@@ -37,6 +37,8 @@
 import java.util.function.Function;
 import sun.util.logging.PlatformLogger;
 
+import jdk.internal.util.StaticProperty;
+
 /**
  * Filter classes, array lengths, and graph metrics during deserialization.
  * If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
@@ -247,7 +249,7 @@
         static {
             configuredFilter = AccessController
                     .doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
-                        String props = System.getProperty(SERIAL_FILTER_PROPNAME);
+                        String props = StaticProperty.jdkSerialFilter();
                         if (props == null) {
                             props = Security.getProperty(SERIAL_FILTER_PROPNAME);
                         }
diff --git a/src/share/classes/sun/misc/SharedSecrets.java b/src/share/classes/sun/misc/SharedSecrets.java
index cc3fc64..d046e4b 100644
--- a/src/share/classes/sun/misc/SharedSecrets.java
+++ b/src/share/classes/sun/misc/SharedSecrets.java
@@ -59,6 +59,7 @@
     private static JavaAWTAccess javaAWTAccess;
     private static JavaOISAccess javaOISAccess;
     private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
+    private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
     private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
 
     public static JavaUtilJarAccess javaUtilJarAccess() {
@@ -202,8 +203,18 @@
         return javaAWTAccess;
     }
 
+    public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
+        if (javaObjectInputStreamReadString == null) {
+            unsafe.ensureClassInitialized(ObjectInputStream.class);
+        }
+        return javaObjectInputStreamReadString;
+    }
 
-   public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
+    public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
+        javaObjectInputStreamReadString = access;
+    }
+
+    public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
         if (javaObjectInputStreamAccess == null) {
             unsafe.ensureClassInitialized(ObjectInputStream.class);
         }
diff --git a/src/share/classes/sun/misc/URLClassPath.java b/src/share/classes/sun/misc/URLClassPath.java
index 6e03510..8d7593f 100644
--- a/src/share/classes/sun/misc/URLClassPath.java
+++ b/src/share/classes/sun/misc/URLClassPath.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -1229,10 +1229,15 @@
             int i = 0;
             while (st.hasMoreTokens()) {
                 String path = st.nextToken();
-                URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path);
+                URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : tryResolve(base, path);
                 if (url != null) {
                     urls[i] = url;
                     i++;
+                } else {
+                    if (DEBUG_CP_URL_CHECK) {
+                        System.err.println("Class-Path entry: \"" + path
+                                           + "\" ignored in JAR file " + base);
+                    }
                 }
             }
             if (i == 0) {
@@ -1244,36 +1249,74 @@
             return urls;
         }
 
-        /*
-         * Return a URL for the given path resolved against the base URL, or
-         * null if the resulting URL is invalid.
+        static URL tryResolve(URL base, String input) throws MalformedURLException {
+            if ("file".equalsIgnoreCase(base.getProtocol())) {
+                return tryResolveFile(base, input);
+            } else {
+                return tryResolveNonFile(base, input);
+            }
+        }
+
+        /**
+         * Attempt to return a file URL by resolving input against a base file
+         * URL. The input is an absolute or relative file URL that encodes a
+         * file path.
+         *
+         * @apiNote Nonsensical input such as a Windows file path with a drive
+         * letter cannot be disambiguated from an absolute URL so will be rejected
+         * (by returning null) by this method.
+         *
+         * @return the resolved URL or null if the input is an absolute URL with
+         *         a scheme other than file (ignoring case)
+         * @throws MalformedURLException
          */
-        static URL safeResolve(URL base, String path) {
-            String child = path.replace(File.separatorChar, '/');
-            try {
-                if (!URI.create(child).isAbsolute()) {
-                    URL url = new URL(base, child);
-                    if (base.getProtocol().equalsIgnoreCase("file")) {
-                        return url;
-                    } else {
-                        String bp = base.getPath();
-                        String urlp = url.getPath();
-                        int pos = bp.lastIndexOf('/');
-                        if (pos == -1) {
-                            pos = bp.length() - 1;
-                        }
-                        if (urlp.regionMatches(0, bp, 0, pos + 1)
-                            && urlp.indexOf("..", pos) == -1) {
-                            return url;
-                        }
-                    }
+        static URL tryResolveFile(URL base, String input) throws MalformedURLException {
+            int index = input.indexOf(':');
+            boolean isFile;
+            if (index >= 0) {
+                String scheme = input.substring(0, index);
+                isFile = "file".equalsIgnoreCase(scheme);
+            } else {
+                isFile = true;
+            }
+            return (isFile) ? new URL(base, input) : null;
+        }
+
+        /**
+         * Attempt to return a URL by resolving input against a base URL. Returns
+         * null if the resolved URL is not contained by the base URL.
+         *
+         * @return the resolved URL or null
+         * @throws MalformedURLException
+         */
+        static URL tryResolveNonFile(URL base, String input) throws MalformedURLException {
+            String child = input.replace(File.separatorChar, '/');
+            if (isRelative(child)) {
+                URL url = new URL(base, child);
+                String bp = base.getPath();
+                String urlp = url.getPath();
+                int pos = bp.lastIndexOf('/');
+                if (pos == -1) {
+                    pos = bp.length() - 1;
                 }
-            } catch (MalformedURLException | IllegalArgumentException e) {}
-            if (DEBUG_CP_URL_CHECK) {
-                System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);
+                if (urlp.regionMatches(0, bp, 0, pos + 1)
+                        && urlp.indexOf("..", pos) == -1) {
+                    return url;
+                }
             }
             return null;
         }
+
+        /**
+         * Returns true if the given input is a relative URI.
+         */
+        static boolean isRelative(String child) {
+            try {
+                return !URI.create(child).isAbsolute();
+            } catch (IllegalArgumentException e) {
+                return false;
+            }
+        }
     }
 
     /*
diff --git a/src/share/classes/sun/net/www/MessageHeader.java b/src/share/classes/sun/net/www/MessageHeader.java
index 34b6307..6ab2008 100644
--- a/src/share/classes/sun/net/www/MessageHeader.java
+++ b/src/share/classes/sun/net/www/MessageHeader.java
@@ -288,14 +288,44 @@
         return Collections.unmodifiableMap(m);
     }
 
+    /** Check if a line of message header looks like a request line.
+     * This method does not perform a full validation but simply
+     * returns false if the line does not end with 'HTTP/[1-9].[0-9]'
+     * @param line the line to check.
+     * @return true if the line might be a request line.
+     */
+    private boolean isRequestline(String line) {
+        String k = line.trim();
+        int i = k.lastIndexOf(' ');
+        if (i <= 0) return false;
+        int len = k.length();
+        if (len - i < 9) return false;
+
+        char c1 = k.charAt(len-3);
+        char c2 = k.charAt(len-2);
+        char c3 = k.charAt(len-1);
+        if (c1 < '1' || c1 > '9') return false;
+        if (c2 != '.') return false;
+        if (c3 < '0' || c3 > '9') return false;
+
+        return (k.substring(i+1, len-3).equalsIgnoreCase("HTTP/"));
+    }
+
+
     /** Prints the key-value pairs represented by this
-        header.  Also prints the RFC required blank line
-        at the end. Omits pairs with a null key. */
+        header. Also prints the RFC required blank line
+        at the end. Omits pairs with a null key. Omits
+        colon if key-value pair is the requestline. */
     public synchronized void print(PrintStream p) {
         for (int i = 0; i < nkeys; i++)
             if (keys[i] != null) {
-                p.print(keys[i] +
-                    (values[i] != null ? ": "+values[i]: "") + "\r\n");
+                StringBuilder sb = new StringBuilder(keys[i]);
+                if (values[i] != null) {
+                    sb.append(": " + values[i]);
+                } else if (i != 0 || !isRequestline(keys[i])) {
+                    sb.append(":");
+                }
+                p.print(sb.append("\r\n"));
             }
         p.print("\r\n");
         p.flush();
diff --git a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
index 53e84d4..b91093f 100644
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -49,9 +49,6 @@
 
     // Our file descriptor
     private final FileDescriptor fd;
-
-    // fd value needed for dev/poll. This value will remain valid
-    // even after the value in the file descriptor object has been set to -1
     private final int fdVal;
 
     // The protocol family of the socket
@@ -103,7 +100,6 @@
 
     // -- End of fields protected by stateLock
 
-
     public DatagramChannelImpl(SelectorProvider sp)
         throws IOException
     {
@@ -138,16 +134,27 @@
                 throw new UnsupportedOperationException("IPv6 not available");
             }
         }
-        this.family = family;
-        this.fd = Net.socket(family, false);
-        this.fdVal = IOUtil.fdVal(fd);
-        this.state = ST_UNCONNECTED;
+
+        ResourceManager.beforeUdpCreate();
+        try {
+            this.family = family;
+            this.fd = Net.socket(family, false);
+            this.fdVal = IOUtil.fdVal(fd);
+            this.state = ST_UNCONNECTED;
+        } catch (IOException ioe) {
+            ResourceManager.afterUdpClose();
+            throw ioe;
+        }
     }
 
     public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd)
         throws IOException
     {
         super(sp);
+
+        // increment UDP count to match decrement when closing
+        ResourceManager.beforeUdpCreate();
+
         this.family = Net.isIPv6Available() ?
             StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
         this.fd = fd;
@@ -742,10 +749,9 @@
                     localAddress = Net.localAddress(fd);
 
                     // flush any packets already received.
-                    boolean blocking = false;
                     synchronized (blockingLock()) {
+                        boolean blocking = isBlocking();
                         try {
-                            blocking = isBlocking();
                             // remainder of each packet thrown away
                             ByteBuffer tmpBuf = ByteBuffer.allocate(1);
                             if (blocking) {
diff --git a/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
index fe2ed23..838a02d 100644
--- a/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
+++ b/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -25,10 +25,22 @@
 
 package sun.nio.ch;
 
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.DatagramSocketImpl;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.net.SocketTimeoutException;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.IllegalBlockingModeException;
 
 
 // Make a datagram-socket channel look like a datagram socket.
@@ -178,7 +190,6 @@
 
         dc.configureBlocking(false);
         try {
-            int n;
             SocketAddress sender;
             if ((sender = dc.receive(bb)) != null)
                 return sender;
@@ -188,19 +199,18 @@
                      throw new ClosedChannelException();
                 long st = System.currentTimeMillis();
                 int result = dc.poll(Net.POLLIN, to);
-                if (result > 0 &&
-                        ((result & Net.POLLIN) != 0)) {
+                if (result > 0 && ((result & Net.POLLIN) != 0)) {
                     if ((sender = dc.receive(bb)) != null)
                         return sender;
                 }
                 to -= System.currentTimeMillis() - st;
                 if (to <= 0)
                     throw new SocketTimeoutException();
-
             }
         } finally {
-            if (dc.isOpen())
+            try {
                 dc.configureBlocking(true);
+            } catch (ClosedChannelException e) { }
         }
     }
 
diff --git a/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java b/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
index 4357ffc..63574ac 100644
--- a/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
+++ b/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -25,9 +25,20 @@
 
 package sun.nio.ch;
 
-import java.io.*;
-import java.net.*;
-import java.nio.channels.*;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.StandardSocketOptions;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
 
 
 // Make a server-socket channel look like a server socket.
@@ -37,7 +48,7 @@
 // class.
 //
 
-public class ServerSocketAdaptor                        // package-private
+class ServerSocketAdaptor                        // package-private
     extends ServerSocket
 {
 
@@ -97,12 +108,16 @@
                 throw new IllegalBlockingModeException();
             try {
                 if (timeout == 0) {
+                    // for compatibility reasons: accept connection if available
+                    // when configured non-blocking
                     SocketChannel sc = ssc.accept();
                     if (sc == null && !ssc.isBlocking())
                         throw new IllegalBlockingModeException();
                     return sc.socket();
                 }
 
+                if (!ssc.isBlocking())
+                    throw new IllegalBlockingModeException();
                 ssc.configureBlocking(false);
                 try {
                     SocketChannel sc;
@@ -121,10 +136,10 @@
                             throw new SocketTimeoutException();
                     }
                 } finally {
-                    if (ssc.isOpen())
+                    try {
                         ssc.configureBlocking(true);
+                    } catch (ClosedChannelException e) { }
                 }
-
             } catch (Exception x) {
                 Net.translateException(x);
                 assert false;
@@ -178,8 +193,7 @@
         if (!isBound())
             return "ServerSocket[unbound]";
         return "ServerSocket[addr=" + getInetAddress() +
-            //          ",port=" + getPort() +
-                ",localport=" + getLocalPort()  + "]";
+               ",localport=" + getLocalPort()  + "]";
     }
 
     public void setReceiveBufferSize(int size) throws SocketException {
diff --git a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
index ee5ff76..563f948 100644
--- a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
+++ b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
@@ -48,10 +48,7 @@
 
     // Our file descriptor
     private final FileDescriptor fd;
-
-    // fd value needed for dev/poll. This value will remain valid
-    // even after the value in the file descriptor object has been set to -1
-    private int fdVal;
+    private final int fdVal;
 
     // ID of native thread currently blocked in this channel, for signalling
     private volatile long thread = 0;
diff --git a/src/share/classes/sun/nio/ch/SocketAdaptor.java b/src/share/classes/sun/nio/ch/SocketAdaptor.java
index d115b7a..c128dc5 100644
--- a/src/share/classes/sun/nio/ch/SocketAdaptor.java
+++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -25,11 +25,23 @@
 
 package sun.nio.ch;
 
-import java.io.*;
-import java.lang.ref.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketOption;
+import java.net.SocketTimeoutException;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.SocketChannel;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 import java.util.*;
@@ -47,7 +59,7 @@
 // java.net.Socket so as to simplify tracking future changes to that class.
 //
 
-public class SocketAdaptor
+class SocketAdaptor
     extends Socket
 {
 
@@ -91,7 +103,6 @@
                 throw new IllegalBlockingModeException();
 
             try {
-
                 if (timeout == 0) {
                     sc.connect(remote);
                     return;
@@ -119,8 +130,9 @@
                         }
                     }
                 } finally {
-                    if (sc.isOpen())
+                    try {
                         sc.configureBlocking(true);
+                    } catch (ClosedChannelException e) { }
                 }
 
             } catch (Exception x) {
@@ -188,10 +200,11 @@
             synchronized (sc.blockingLock()) {
                 if (!sc.isBlocking())
                     throw new IllegalBlockingModeException();
+
                 if (timeout == 0)
                     return sc.read(bb);
-                sc.configureBlocking(false);
 
+                sc.configureBlocking(false);
                 try {
                     int n;
                     if ((n = sc.read(bb)) != 0)
@@ -211,10 +224,10 @@
                             throw new SocketTimeoutException();
                     }
                 } finally {
-                    if (sc.isOpen())
+                    try {
                         sc.configureBlocking(true);
+                    } catch (ClosedChannelException e) { }
                 }
-
             }
         }
     }
diff --git a/src/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/share/classes/sun/nio/ch/SocketChannelImpl.java
index 7b694ef..164a165 100644
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -50,9 +50,6 @@
 
     // Our file descriptor object
     private final FileDescriptor fd;
-
-    // fd value needed for dev/poll. This value will remain valid
-    // even after the value in the file descriptor object has been set to -1
     private final int fdVal;
 
     // IDs of native threads doing reads and writes, for signalling
diff --git a/src/share/classes/sun/reflect/misc/MethodUtil.java b/src/share/classes/sun/reflect/misc/MethodUtil.java
index ebe802b..e48ec1d 100644
--- a/src/share/classes/sun/reflect/misc/MethodUtil.java
+++ b/src/share/classes/sun/reflect/misc/MethodUtil.java
@@ -25,6 +25,7 @@
 
 package sun.reflect.misc;
 
+import java.io.EOFException;
 import java.security.AllPermission;
 import java.security.AccessController;
 import java.security.PermissionCollection;
@@ -42,8 +43,8 @@
 import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import java.util.Map;
-import sun.misc.IOUtils;
 
+import sun.misc.IOUtils;
 
 class Trampoline {
     static {
@@ -382,15 +383,12 @@
             }
         }
         int len = uc.getContentLength();
-        InputStream in = new BufferedInputStream(uc.getInputStream());
-
-        byte[] b;
-        try {
-            b = IOUtils.readFully(in, len, true);
-        } finally {
-            in.close();
+        try (InputStream in = new BufferedInputStream(uc.getInputStream())) {
+            byte[] b = IOUtils.readAllBytes(in);
+            if (len != -1 && b.length != len)
+                throw new EOFException("Expected:" + len + ", read:" + b.length);
+            return b;
         }
-        return b;
     }
 
 
diff --git a/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java b/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
index c0a06f1..2d9102f 100644
--- a/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
@@ -27,7 +27,9 @@
 package sun.rmi.registry;
 
 import java.io.IOException;
+import java.io.ObjectInputStream;
 
+import sun.misc.SharedSecrets;
 import sun.rmi.transport.StreamRemoteCall;
 
 /**
@@ -83,8 +85,9 @@
                 java.lang.String $param_String_1;
                 java.rmi.Remote $param_Remote_2;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
                     $param_Remote_2 = (java.rmi.Remote) in.readObject();
                 } catch (ClassCastException | IOException | ClassNotFoundException e) {
                     call.discardPendingRefs();
@@ -118,9 +121,10 @@
             {
                 java.lang.String $param_String_1;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
-                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
+                } catch (ClassCastException | IOException e) {
                     call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
@@ -144,8 +148,9 @@
                 java.lang.String $param_String_1;
                 java.rmi.Remote $param_Remote_2;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
                     $param_Remote_2 = (java.rmi.Remote) in.readObject();
                 } catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
                     call.discardPendingRefs();
@@ -169,9 +174,10 @@
 
                 java.lang.String $param_String_1;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
-                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
+                } catch (ClassCastException | IOException e) {
                     call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
diff --git a/src/share/classes/sun/rmi/server/UnicastRef.java b/src/share/classes/sun/rmi/server/UnicastRef.java
index 831c41b..b01a2b8 100644
--- a/src/share/classes/sun/rmi/server/UnicastRef.java
+++ b/src/share/classes/sun/rmi/server/UnicastRef.java
@@ -27,6 +27,7 @@
 
 import java.io.IOException;
 import java.io.ObjectInput;
+import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
 import java.lang.reflect.Method;
 import java.rmi.MarshalException;
@@ -38,6 +39,8 @@
 import java.rmi.server.RemoteObject;
 import java.rmi.server.RemoteRef;
 import java.security.AccessController;
+
+import sun.misc.SharedSecrets;
 import sun.rmi.runtime.Log;
 import sun.rmi.transport.Connection;
 import sun.rmi.transport.LiveRef;
@@ -318,6 +321,8 @@
             } else {
                 throw new Error("Unrecognized primitive type: " + type);
             }
+        } else if (type == String.class && in instanceof ObjectInputStream) {
+            return SharedSecrets.getJavaObjectInputStreamReadString().readString((ObjectInputStream)in);
         } else {
             return in.readObject();
         }
diff --git a/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java b/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
index d733821..0d849ed 100644
--- a/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
+++ b/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -29,6 +29,7 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.lang.reflect.Proxy;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
@@ -553,6 +554,9 @@
             host = in.readUTF();
             port = in.readInt();
             csf = (RMIClientSocketFactory) in.readObject();
+            if (Proxy.isProxyClass(csf.getClass())) {
+                throw new IOException("Invalid SocketFactory");
+            }
           break;
 
           default:
diff --git a/src/share/classes/sun/security/action/GetPropertyAction.java b/src/share/classes/sun/security/action/GetPropertyAction.java
index 24ecc91..59bf324 100644
--- a/src/share/classes/sun/security/action/GetPropertyAction.java
+++ b/src/share/classes/sun/security/action/GetPropertyAction.java
@@ -108,4 +108,27 @@
                     new GetPropertyAction(theProp));
         }
     }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * Note that this method performs a privileged action using caller-provided
+     * inputs. The caller of this method should take care to ensure that the
+     * inputs are not tainted and the returned property is not made accessible
+     * to untrusted code if it contains sensitive information.
+     *
+     * @param theProp the name of the system property.
+     * @param defaultVal the default value.
+     */
+    public static String privilegedGetProperty(String theProp,
+            String defaultVal) {
+        if (System.getSecurityManager() == null) {
+            return System.getProperty(theProp, defaultVal);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetPropertyAction(theProp, defaultVal));
+        }
+    }
 }
diff --git a/src/share/classes/sun/security/jgss/krb5/CipherHelper.java b/src/share/classes/sun/security/jgss/krb5/CipherHelper.java
index c637b01..0b8adfb 100644
--- a/src/share/classes/sun/security/jgss/krb5/CipherHelper.java
+++ b/src/share/classes/sun/security/jgss/krb5/CipherHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -44,6 +44,7 @@
 import sun.security.krb5.internal.crypto.Aes128;
 import sun.security.krb5.internal.crypto.Aes256;
 import sun.security.krb5.internal.crypto.ArcFourHmac;
+import sun.security.krb5.internal.crypto.EType;
 
 class CipherHelper {
 
@@ -77,10 +78,6 @@
     private int sgnAlg, sealAlg;
     private byte[] keybytes;
 
-    // new token format from draft-ietf-krb-wg-gssapi-cfx-07
-    // proto is used to determine new GSS token format for "newer" etypes
-    private int proto = 0;
-
     CipherHelper(EncryptionKey key) throws GSSException {
         etype = key.getEType();
         keybytes = key.getBytes();
@@ -106,7 +103,6 @@
         case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
             sgnAlg = -1;
             sealAlg = -1;
-            proto = 1;
             break;
 
         default:
@@ -123,8 +119,10 @@
         return sealAlg;
     }
 
+    // new token format from draft-ietf-krb-wg-gssapi-cfx-07
+    // proto is used to determine new GSS token format for "newer" etypes
     int getProto() {
-        return proto;
+        return EType.isNewer(etype) ? 1 : 0;
     }
 
     int getEType() {
diff --git a/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java b/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java
index 0077e7e..1688d5c 100644
--- a/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java
+++ b/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -29,6 +29,8 @@
 import org.ietf.jgss.*;
 import java.io.InputStream;
 import java.io.IOException;
+
+import sun.security.action.GetPropertyAction;
 import sun.security.krb5.*;
 import java.net.InetAddress;
 import sun.security.krb5.internal.AuthorizationData;
@@ -36,6 +38,33 @@
 
 class InitSecContextToken extends InitialToken {
 
+    // If non-mutual authentication is requested, there is no AP-REP message.
+    // The acceptor thus has no chance to send the seq-number field to the
+    // initiator. In this case, the initiator and acceptor should has an
+    // agreement to derive acceptor's initial seq-number if the acceptor wishes
+    // to send messages to the initiator.
+
+    // If this flag is true, it will the same as the initiator's initial
+    // seq-number (as MIT krb5 and Windows SSPI do). Otherwise, it will be zero
+    // (as Heimdal does). The default value is true.
+    private static final boolean ACCEPTOR_USE_INITIATOR_SEQNUM;
+
+    static {
+        // The ACCEPTOR_USE_INITIATOR_SEQNUM value is determined by the system
+        // property "sun.security.krb5.acceptor.sequence.number.nonmutual",
+        // which can be set to "initiator", "zero" or "0".
+        String propName = "sun.security.krb5.acceptor.sequence.number.nonmutual";
+        String s = GetPropertyAction.privilegedGetProperty(propName, "initiator");
+        if (s.equals("initiator")) {
+            ACCEPTOR_USE_INITIATOR_SEQNUM = true;
+        } else if (s.equals("zero") || s.equals("0")) {
+            ACCEPTOR_USE_INITIATOR_SEQNUM = false;
+        } else {
+            throw new AssertionError("Unrecognized value for " + propName
+                    + ": " + s);
+        }
+    }
+
     private KrbApReq apReq = null;
 
     /**
@@ -79,7 +108,10 @@
             context.setKey(Krb5Context.SESSION_KEY, serviceTicket.getSessionKey());
 
         if (!mutualRequired)
-            context.resetPeerSequenceNumber(0);
+            context.resetPeerSequenceNumber(
+                    ACCEPTOR_USE_INITIATOR_SEQNUM
+                    ? apReq.getSeqNumber().intValue()
+                    : 0);
     }
 
     /**
@@ -144,10 +176,12 @@
                              apReqSeqNumber.intValue() :
                              0);
         context.resetPeerSequenceNumber(peerSeqNumber);
-        if (!context.getMutualAuthState())
-            // Use the same sequence number as the peer
-            // (Behaviour exhibited by the Windows SSPI server)
-            context.resetMySequenceNumber(peerSeqNumber);
+        if (!context.getMutualAuthState()) {
+            context.resetMySequenceNumber(
+                    ACCEPTOR_USE_INITIATOR_SEQNUM
+                            ? peerSeqNumber
+                            : 0);
+        }
         context.setAuthTime(
                 new KerberosTime(apReq.getCreds().getAuthTime()).toString());
         context.setTktFlags(apReq.getCreds().getFlags());
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
index a0658d0..e9ee13d 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
@@ -713,14 +713,14 @@
                             if (subject != null &&
                                 !subject.isReadOnly()) {
                                 /*
-                             * Store the service credentials as
-                             * javax.security.auth.kerberos.KerberosTicket in
-                             * the Subject. We could wait till the context is
-                             * succesfully established; however it is easier
-                             * to do here and there is no harm indoing it here.
-                             */
+                                * Store the service credentials as
+                                * javax.security.auth.kerberos.KerberosTicket in
+                                * the Subject. We could wait until the context is
+                                * successfully established; however it is easier
+                                * to do it here and there is no harm.
+                                */
                                 final KerberosTicket kt =
-                                    Krb5Util.credsToTicket(serviceCreds);
+                                        Krb5Util.credsToTicket(serviceCreds);
                                 AccessController.doPrivileged (
                                     new java.security.PrivilegedAction<Void>() {
                                       public Void run() {
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java b/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
index daefbbc..314cabb 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
@@ -60,7 +60,9 @@
     private Krb5InitCredential(Krb5NameElement name,
                                byte[] asn1Encoding,
                                KerberosPrincipal client,
+                               KerberosPrincipal clientAlias,
                                KerberosPrincipal server,
+                               KerberosPrincipal serverAlias,
                                byte[] sessionKey,
                                int keyType,
                                boolean[] flags,
@@ -81,14 +83,21 @@
               endTime,
               renewTill,
               clientAddresses);
-
+        KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketSetClientAlias(this, clientAlias);
+        KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketSetServerAlias(this, serverAlias);
         this.name = name;
 
         try {
             // Cache this for later use by the sun.security.krb5 package.
             krb5Credentials = new Credentials(asn1Encoding,
                                               client.getName(),
+                                              (clientAlias != null ?
+                                                      clientAlias.getName() : null),
                                               server.getName(),
+                                              (serverAlias != null ?
+                                                      serverAlias.getName() : null),
                                               sessionKey,
                                               keyType,
                                               flags,
@@ -111,7 +120,9 @@
                                Credentials delegatedCred,
                                byte[] asn1Encoding,
                                KerberosPrincipal client,
+                               KerberosPrincipal clientAlias,
                                KerberosPrincipal server,
+                               KerberosPrincipal serverAlias,
                                byte[] sessionKey,
                                int keyType,
                                boolean[] flags,
@@ -132,7 +143,10 @@
               endTime,
               renewTill,
               clientAddresses);
-
+        KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketSetClientAlias(this, clientAlias);
+        KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketSetServerAlias(this, serverAlias);
         this.name = name;
         // A delegated cred does not have all fields set. So do not try to
         // creat new Credentials out of the delegatedCred.
@@ -154,10 +168,18 @@
                                        Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
         }
 
+        KerberosPrincipal clientAlias = KerberosSecrets
+                .getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketGetClientAlias(tgt);
+        KerberosPrincipal serverAlias = KerberosSecrets
+                .getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketGetServerAlias(tgt);
         Krb5InitCredential result = new Krb5InitCredential(name,
                                       tgt.getEncoded(),
                                       tgt.getClient(),
+                                      clientAlias,
                                       tgt.getServer(),
+                                      serverAlias,
                                       tgt.getSessionKey().getEncoded(),
                                       tgt.getSessionKeyType(),
                                       tgt.getFlags(),
@@ -183,10 +205,14 @@
          */
 
         PrincipalName cPrinc = delegatedCred.getClient();
+        PrincipalName cAPrinc = delegatedCred.getClientAlias();
         PrincipalName sPrinc = delegatedCred.getServer();
+        PrincipalName sAPrinc = delegatedCred.getServerAlias();
 
         KerberosPrincipal client = null;
+        KerberosPrincipal clientAlias = null;
         KerberosPrincipal server = null;
+        KerberosPrincipal serverAlias = null;
 
         Krb5NameElement credName = null;
 
@@ -197,6 +223,10 @@
             client =  new KerberosPrincipal(fullName);
         }
 
+        if (cAPrinc != null) {
+            clientAlias = new KerberosPrincipal(cAPrinc.getName());
+        }
+
         // XXX Compare name to credName
 
         if (sPrinc != null) {
@@ -205,11 +235,17 @@
                                         KerberosPrincipal.KRB_NT_SRV_INST);
         }
 
+        if (sAPrinc != null) {
+            serverAlias = new KerberosPrincipal(sAPrinc.getName());
+        }
+
         return new Krb5InitCredential(credName,
                                       delegatedCred,
                                       delegatedCred.getEncoded(),
                                       client,
+                                      clientAlias,
                                       server,
+                                      serverAlias,
                                       sessionKey.getBytes(),
                                       sessionKey.getEType(),
                                       delegatedCred.getFlags(),
diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5Util.java b/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
index 8f79df1..387edd7 100644
--- a/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
+++ b/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
@@ -228,7 +228,7 @@
 
     public static KerberosTicket credsToTicket(Credentials serviceCreds) {
         EncryptionKey sessionKey =  serviceCreds.getSessionKey();
-        return new KerberosTicket(
+        KerberosTicket kt = new KerberosTicket(
             serviceCreds.getEncoded(),
             new KerberosPrincipal(serviceCreds.getClient().getName()),
             new KerberosPrincipal(serviceCreds.getServer().getName(),
@@ -241,14 +241,35 @@
             serviceCreds.getEndTime(),
             serviceCreds.getRenewTill(),
             serviceCreds.getClientAddresses());
+        PrincipalName clientAlias = serviceCreds.getClientAlias();
+        PrincipalName serverAlias = serviceCreds.getServerAlias();
+        if (clientAlias != null) {
+            KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                    .kerberosTicketSetClientAlias(kt, new KerberosPrincipal(
+                            clientAlias.getName(), clientAlias.getNameType()));
+        }
+        if (serverAlias != null) {
+            KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                    .kerberosTicketSetServerAlias(kt, new KerberosPrincipal(
+                            serverAlias.getName(), serverAlias.getNameType()));
+        }
+        return kt;
     };
 
     public static Credentials ticketToCreds(KerberosTicket kerbTicket)
             throws KrbException, IOException {
+        KerberosPrincipal clientAlias = KerberosSecrets
+                .getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketGetClientAlias(kerbTicket);
+        KerberosPrincipal serverAlias = KerberosSecrets
+                .getJavaxSecurityAuthKerberosAccess()
+                .kerberosTicketGetServerAlias(kerbTicket);
         return new Credentials(
             kerbTicket.getEncoded(),
             kerbTicket.getClient().getName(),
+            (clientAlias != null ? clientAlias.getName() : null),
             kerbTicket.getServer().getName(),
+            (serverAlias != null ? serverAlias.getName() : null),
             kerbTicket.getSessionKey().getEncoded(),
             kerbTicket.getSessionKeyType(),
             kerbTicket.getFlags(),
diff --git a/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java b/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java
index 7d293ce..808c201 100644
--- a/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java
+++ b/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, 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
@@ -499,11 +499,11 @@
      */
     class MessageTokenHeader {
 
-         private int tokenId;
-         private byte[] bytes = new byte[TOKEN_HEADER_SIZE];
+        private int tokenId;
+        private byte[] bytes = new byte[TOKEN_HEADER_SIZE];
 
-         // Writes a new token header
-         public MessageTokenHeader(int tokenId, boolean conf) throws GSSException {
+        // Writes a new token header
+        public MessageTokenHeader(int tokenId, boolean conf) throws GSSException {
 
             this.tokenId = tokenId;
 
@@ -609,7 +609,7 @@
             prop.setQOP(0);
 
             // sequence number
-            seqNumber = readBigEndian(bytes, 0, 8);
+            seqNumber = readBigEndian(bytes, 12, 4);
         }
 
         /**
diff --git a/src/share/classes/sun/security/jgss/krb5/SubjectComber.java b/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
index a7100f0..1bc1bf7 100644
--- a/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
+++ b/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -25,6 +25,8 @@
 
 package sun.security.jgss.krb5;
 
+import sun.security.krb5.KerberosSecrets;
+
 import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.Subject;
@@ -182,24 +184,45 @@
 
                                 }
                             } else {
+                                KerberosPrincipal serverAlias = KerberosSecrets
+                                        .getJavaxSecurityAuthKerberosAccess()
+                                        .kerberosTicketGetServerAlias(ticket);
                                 if (serverPrincipal == null ||
-                                    ticket.getServer().getName().equals(serverPrincipal))  {
-
+                                    ticket.getServer().getName().equals(serverPrincipal) ||
+                                            (serverAlias != null &&
+                                                    serverPrincipal.equals(
+                                                            serverAlias.getName())))  {
+                                    KerberosPrincipal clientAlias = KerberosSecrets
+                                            .getJavaxSecurityAuthKerberosAccess()
+                                            .kerberosTicketGetClientAlias(ticket);
                                     if (clientPrincipal == null ||
                                         clientPrincipal.equals(
-                                            ticket.getClient().getName())) {
+                                            ticket.getClient().getName()) ||
+                                            (clientAlias != null &&
+                                            clientPrincipal.equals(
+                                                    clientAlias.getName()))) {
                                         if (oneOnly) {
                                             return ticket;
                                         } else {
                                             // Record names so that tickets will
                                             // all belong to same principals
                                             if (clientPrincipal == null) {
-                                                clientPrincipal =
-                                                ticket.getClient().getName();
+                                                if (clientAlias == null) {
+                                                    clientPrincipal =
+                                                            ticket.getClient().getName();
+                                                } else {
+                                                    clientPrincipal =
+                                                            clientAlias.getName();
+                                                }
                                             }
                                             if (serverPrincipal == null) {
-                                                serverPrincipal =
-                                                ticket.getServer().getName();
+                                                if (serverAlias == null) {
+                                                    serverPrincipal =
+                                                            ticket.getServer().getName();
+                                                } else {
+                                                    serverPrincipal =
+                                                            serverAlias.getName();
+                                                }
                                             }
                                             answer.add(credClass.cast(ticket));
                                         }
diff --git a/src/share/classes/sun/security/krb5/Checksum.java b/src/share/classes/sun/security/krb5/Checksum.java
index 6a7f491..92a5de8 100644
--- a/src/share/classes/sun/security/krb5/Checksum.java
+++ b/src/share/classes/sun/security/krb5/Checksum.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -69,6 +69,7 @@
     // draft-brezak-win2k-krb-rc4-hmac-04.txt
     public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138;
 
+    // default checksum type, -1 if not set
     static int CKSUMTYPE_DEFAULT;
     static int SAFECKSUMTYPE_DEFAULT;
 
@@ -83,26 +84,19 @@
         try {
             cfg = Config.getInstance();
             temp = cfg.get("libdefaults", "default_checksum");
-            if (temp != null)
-                {
-                    CKSUMTYPE_DEFAULT = Config.getType(temp);
-                } else {
-                    /*
-                     * If the default checksum is not
-                     * specified in the configuration we
-                     * set it to RSA_MD5. We follow the MIT and
-                     * SEAM implementation.
-                     */
-                    CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
-                }
+            if (temp != null) {
+                CKSUMTYPE_DEFAULT = Config.getType(temp);
+            } else {
+                CKSUMTYPE_DEFAULT = -1;
+            }
         } catch (Exception exc) {
             if (DEBUG) {
                 System.out.println("Exception in getting default checksum "+
-                                   "value from the configuration " +
-                                   "Setting default checksum to be RSA-MD5");
+                                   "value from the configuration. " +
+                                   "No default checksum set.");
                 exc.printStackTrace();
             }
-            CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
+            CKSUMTYPE_DEFAULT = -1;
         }
 
 
@@ -112,97 +106,100 @@
                 {
                     SAFECKSUMTYPE_DEFAULT = Config.getType(temp);
                 } else {
-                    SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
+                    SAFECKSUMTYPE_DEFAULT = -1;
                 }
         } catch (Exception exc) {
             if (DEBUG) {
                 System.out.println("Exception in getting safe default " +
                                    "checksum value " +
-                                   "from the configuration Setting  " +
-                                   "safe default checksum to be RSA-MD5");
+                                   "from the configuration Setting.  " +
+                                   "No safe default checksum set.");
                 exc.printStackTrace();
             }
-            SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
+            SAFECKSUMTYPE_DEFAULT = -1;
         }
     }
 
     /**
      * Constructs a new Checksum using the raw data and type.
+     *
+     * This constructor is only used by Authenticator Checksum
+     * {@link sun.security.jgss.krb5.InitialToken.OverloadedChecksum}
+     * where the checksum type must be 0x8003
+     * (see https://tools.ietf.org/html/rfc4121#section-4.1.1)
+     * and checksum field/value is used to convey service flags,
+     * channel bindings, and optional delegation information.
+     * This special type does NOT have a {@link CksumType} and has its
+     * own calculating and verification rules. It does has the same
+     * ASN.1 encoding though.
+     *
      * @data the byte array of checksum.
      * @new_cksumType the type of checksum.
-     *
      */
-         // used in InitialToken
     public Checksum(byte[] data, int new_cksumType) {
         cksumType = new_cksumType;
         checksum = data;
     }
 
     /**
-     * Constructs a new Checksum by calculating the checksum over the data
-     * using specified checksum type.
-     * @new_cksumType the type of checksum.
-     * @data the data that needs to be performed a checksum calculation on.
+     * Constructs a new Checksum by calculating over the data using
+     * the specified checksum type. If the checksum is unkeyed, key
+     * and usage are ignored.
+     *
+     * @param new_cksumType the type of checksum. If set to -1, the
+     *      {@linkplain EType#checksumType() mandatory checksum type}
+     *      for the encryption type of {@code key} will be used
+     * @param data the data that needs to be performed a checksum calculation on
+     * @param key the key used by a keyed checksum
+     * @param usage the usage used by a keyed checksum
      */
-    public Checksum(int new_cksumType, byte[] data)
-        throws KdcErrException, KrbCryptoException {
-
-        cksumType = new_cksumType;
-        CksumType cksumEngine = CksumType.getInstance(cksumType);
-        if (!cksumEngine.isSafe()) {
-            checksum = cksumEngine.calculateChecksum(data, data.length);
-        } else {
-            throw new KdcErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
-        }
-    }
-
-    /**
-     * Constructs a new Checksum by calculating the keyed checksum
-     * over the data using specified checksum type.
-     * @new_cksumType the type of checksum.
-     * @data the data that needs to be performed a checksum calculation on.
-     */
-         // KrbSafe, KrbTgsReq
     public Checksum(int new_cksumType, byte[] data,
-                        EncryptionKey key, int usage)
-        throws KdcErrException, KrbApErrException, KrbCryptoException {
-        cksumType = new_cksumType;
-        CksumType cksumEngine = CksumType.getInstance(cksumType);
-        if (!cksumEngine.isSafe())
-            throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
-        checksum =
-            cksumEngine.calculateKeyedChecksum(data,
-                data.length,
-                key.getBytes(),
-                usage);
+                    EncryptionKey key, int usage)
+            throws KdcErrException, KrbApErrException, KrbCryptoException {
+        if (new_cksumType == -1) {
+            cksumType = EType.getInstance(key.getEType()).checksumType();
+        } else {
+            cksumType = new_cksumType;
+        }
+        checksum = CksumType.getInstance(cksumType).calculateChecksum(
+                    data, data.length, key.getBytes(), usage);
     }
 
     /**
      * Verifies the keyed checksum over the data passed in.
      */
-    public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key,
-                                        int usage)
-        throws KdcErrException, KrbApErrException, KrbCryptoException {
+    public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage)
+            throws KdcErrException, KrbApErrException, KrbCryptoException {
         CksumType cksumEngine = CksumType.getInstance(cksumType);
-        if (!cksumEngine.isSafe())
+        if (!cksumEngine.isKeyed()) {
             throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
-        return cksumEngine.verifyKeyedChecksum(data,
-                                               data.length,
-                                               key.getBytes(),
-                                               checksum,
-            usage);
+        } else {
+            return cksumEngine.verifyChecksum(
+                    data, data.length, key.getBytes(), checksum, usage);
+        }
     }
 
-    /*
-    public Checksum(byte[] data) throws KdcErrException, KrbCryptoException {
-        this(Checksum.CKSUMTYPE_DEFAULT, data);
+
+    /**
+     * Verifies the checksum over the data passed in. The checksum might
+     * be a keyed or not.
+     *
+     * ===============  ATTENTION! Use with care  ==================
+     * According to https://tools.ietf.org/html/rfc3961#section-6.1,
+     * An unkeyed checksum should only be used "in limited circumstances
+     * where the lack of a key does not provide a window for an attack,
+     * preferably as part of an encrypted message".
+     */
+    public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
+            throws KdcErrException, KrbCryptoException {
+        return CksumType.getInstance(cksumType).verifyChecksum(
+                data, data.length, key.getBytes(), checksum, usage);
     }
-    */
 
     boolean isEqual(Checksum cksum) throws KdcErrException {
-        if (cksumType != cksum.cksumType)
+        if (cksumType != cksum.cksumType) {
             return false;
-        CksumType cksumEngine = CksumType.getInstance(cksumType);
+        }
         return CksumType.isChecksumEqual(checksum, cksum.checksum);
     }
 
@@ -214,7 +211,7 @@
      * @exception IOException if an I/O error occurs while reading encoded data.
      *
      */
-    private Checksum(DerValue encoding) throws Asn1Exception, IOException {
+    public Checksum(DerValue encoding) throws Asn1Exception, IOException {
         DerValue der;
         if (encoding.getTag() != DerValue.tag_Sequence) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
diff --git a/src/share/classes/sun/security/krb5/Config.java b/src/share/classes/sun/security/krb5/Config.java
index 7ee9231..fe6565c 100644
--- a/src/share/classes/sun/security/krb5/Config.java
+++ b/src/share/classes/sun/security/krb5/Config.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -30,25 +30,24 @@
  */
 package sun.security.krb5;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.ArrayList;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.util.StringTokenizer;
+import java.io.*;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Hashtable;
 import java.util.List;
 import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import sun.net.dns.ResolverConfiguration;
 import sun.security.krb5.internal.crypto.EType;
 import sun.security.krb5.internal.Krb5;
+import sun.security.util.SecurityProperties;
 
 /**
  * This class maintains key-value pairs of Kerberos configurable constants
@@ -57,6 +56,41 @@
 
 public class Config {
 
+    /**
+     * {@systemProperty sun.security.krb5.disableReferrals} property
+     * indicating whether or not cross-realm referrals (RFC 6806) are
+     * enabled.
+     */
+    public static final boolean DISABLE_REFERRALS;
+
+    /**
+     * {@systemProperty sun.security.krb5.maxReferrals} property
+     * indicating the maximum number of cross-realm referral
+     * hops allowed.
+     */
+    public static final int MAX_REFERRALS;
+
+    static {
+        String disableReferralsProp =
+                SecurityProperties.privilegedGetOverridable(
+                        "sun.security.krb5.disableReferrals");
+        if (disableReferralsProp != null) {
+            DISABLE_REFERRALS = "true".equalsIgnoreCase(disableReferralsProp);
+        } else {
+            DISABLE_REFERRALS = false;
+        }
+
+        int maxReferralsValue = 5;
+        String maxReferralsProp =
+                SecurityProperties.privilegedGetOverridable(
+                        "sun.security.krb5.maxReferrals");
+        try {
+            maxReferralsValue = Integer.parseInt(maxReferralsProp);
+        } catch (NumberFormatException e) {
+        }
+        MAX_REFERRALS = maxReferralsValue;
+    }
+
     /*
      * Only allow a single instance of Config.
      */
@@ -257,7 +291,11 @@
     }
 
     /**
-     * Gets all values for the specified keys.
+     * Gets all values (at least one) for the specified keys separated by
+     * a whitespace, or null if there is no such keys.
+     * The values can either be provided on a single line, or on multiple lines
+     * using the same key. When provided on a single line, the value can be
+     * comma or space separated.
      * @throws IllegalArgumentException if any of the keys is illegal
      *         (See {@link #get})
      */
@@ -267,6 +305,7 @@
         StringBuilder sb = new StringBuilder();
         boolean first = true;
         for (String s: v) {
+            s = s.replaceAll("[\\s,]+", " ");
             if (first) {
                 sb.append(s);
                 first = false;
@@ -314,6 +353,72 @@
     }
 
     /**
+     * Translates a duration value into seconds.
+     *
+     * The format can be one of "h:m[:s]", "NdNhNmNs", and "N". See
+     * http://web.mit.edu/kerberos/krb5-devel/doc/basic/date_format.html#duration
+     * for definitions.
+     *
+     * @param s the string duration
+     * @return time in seconds
+     * @throw KrbException if format is illegal
+     */
+    public static int duration(String s) throws KrbException {
+
+        if (s.isEmpty()) {
+            throw new KrbException("Duration cannot be empty");
+        }
+
+        // N
+        if (s.matches("\\d+")) {
+            return Integer.parseInt(s);
+        }
+
+        // h:m[:s]
+        Matcher m = Pattern.compile("(\\d+):(\\d+)(:(\\d+))?").matcher(s);
+        if (m.matches()) {
+            int hr = Integer.parseInt(m.group(1));
+            int min = Integer.parseInt(m.group(2));
+            if (min >= 60) {
+                throw new KrbException("Illegal duration format " + s);
+            }
+            int result = hr * 3600 + min * 60;
+            if (m.group(4) != null) {
+                int sec = Integer.parseInt(m.group(4));
+                if (sec >= 60) {
+                    throw new KrbException("Illegal duration format " + s);
+                }
+                result += sec;
+            }
+            return result;
+        }
+
+        // NdNhNmNs
+        // 120m allowed. Maybe 1h120m is not good, but still allowed
+        m = Pattern.compile(
+                    "((\\d+)d)?\\s*((\\d+)h)?\\s*((\\d+)m)?\\s*((\\d+)s)?",
+                Pattern.CASE_INSENSITIVE).matcher(s);
+        if (m.matches()) {
+            int result = 0;
+            if (m.group(2) != null) {
+                result += 86400 * Integer.parseInt(m.group(2));
+            }
+            if (m.group(4) != null) {
+                result += 3600 * Integer.parseInt(m.group(4));
+            }
+            if (m.group(6) != null) {
+                result += 60 * Integer.parseInt(m.group(6));
+            }
+            if (m.group(8) != null) {
+                result += Integer.parseInt(m.group(8));
+            }
+            return result;
+        }
+
+        throw new KrbException("Illegal duration format " + s);
+    }
+
+    /**
      * Gets the int value for the specified keys.
      * @param keys the keys
      * @return the int value, Integer.MIN_VALUE is returned if it cannot be
diff --git a/src/share/classes/sun/security/krb5/Credentials.java b/src/share/classes/sun/security/krb5/Credentials.java
index 3fe2953..b364a62 100644
--- a/src/share/classes/sun/security/krb5/Credentials.java
+++ b/src/share/classes/sun/security/krb5/Credentials.java
@@ -48,7 +48,9 @@
 
     Ticket ticket;
     PrincipalName client;
+    PrincipalName clientAlias;
     PrincipalName server;
+    PrincipalName serverAlias;
     EncryptionKey key;
     TicketFlags flags;
     KerberosTime authTime;
@@ -78,7 +80,9 @@
 
     public Credentials(Ticket new_ticket,
                        PrincipalName new_client,
+                       PrincipalName new_client_alias,
                        PrincipalName new_server,
+                       PrincipalName new_server_alias,
                        EncryptionKey new_key,
                        TicketFlags new_flags,
                        KerberosTime authTime,
@@ -87,14 +91,17 @@
                        KerberosTime renewTill,
                        HostAddresses cAddr,
                        AuthorizationData authzData) {
-        this(new_ticket, new_client, new_server, new_key, new_flags,
-                authTime, new_startTime, new_endTime, renewTill, cAddr);
+        this(new_ticket, new_client, new_client_alias, new_server,
+                new_server_alias, new_key, new_flags, authTime,
+                new_startTime, new_endTime, renewTill, cAddr);
         this.authzData = authzData;
     }
 
     public Credentials(Ticket new_ticket,
                        PrincipalName new_client,
+                       PrincipalName new_client_alias,
                        PrincipalName new_server,
+                       PrincipalName new_server_alias,
                        EncryptionKey new_key,
                        TicketFlags new_flags,
                        KerberosTime authTime,
@@ -104,7 +111,9 @@
                        HostAddresses cAddr) {
         ticket = new_ticket;
         client = new_client;
+        clientAlias = new_client_alias;
         server = new_server;
+        serverAlias = new_server_alias;
         key = new_key;
         flags = new_flags;
         this.authTime = authTime;
@@ -116,7 +125,9 @@
 
     public Credentials(byte[] encoding,
                        String client,
+                       String clientAlias,
                        String server,
+                       String serverAlias,
                        byte[] keyBytes,
                        int keyType,
                        boolean[] flags,
@@ -127,7 +138,11 @@
                        InetAddress[] cAddrs) throws KrbException, IOException {
         this(new Ticket(encoding),
              new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL),
+             (clientAlias == null? null : new PrincipalName(clientAlias,
+                     PrincipalName.KRB_NT_PRINCIPAL)),
              new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST),
+             (serverAlias == null? null : new PrincipalName(serverAlias,
+                     PrincipalName.KRB_NT_SRV_INST)),
              new EncryptionKey(keyType, keyBytes),
              (flags == null? null: new TicketFlags(flags)),
              (authTime == null? null: new KerberosTime(authTime)),
@@ -152,10 +167,18 @@
         return client;
     }
 
+    public final PrincipalName getClientAlias() {
+        return clientAlias;
+    }
+
     public final PrincipalName getServer() {
         return server;
     }
 
+    public final PrincipalName getServerAlias() {
+        return serverAlias;
+    }
+
     public final EncryptionKey getSessionKey() {
         return key;
     }
@@ -271,6 +294,7 @@
         return new KrbTgsReq(options,
                              this,
                              server,
+                             serverAlias,
                              null, // from
                              null, // till
                              null, // rtime
@@ -488,7 +512,11 @@
     public static void printDebug(Credentials c) {
         System.out.println(">>> DEBUG: ----Credentials----");
         System.out.println("\tclient: " + c.client.toString());
+        if (c.clientAlias != null)
+            System.out.println("\tclient alias: " + c.clientAlias.toString());
         System.out.println("\tserver: " + c.server.toString());
+        if (c.serverAlias != null)
+            System.out.println("\tserver alias: " + c.serverAlias.toString());
         System.out.println("\tticket: sname: " + c.ticket.sname.toString());
         if (c.startTime != null) {
             System.out.println("\tstartTime: " + c.startTime.getTime());
@@ -516,7 +544,11 @@
     public String toString() {
         StringBuffer buffer = new StringBuffer("Credentials:");
         buffer.append(    "\n      client=").append(client);
+        if (clientAlias != null)
+            buffer.append(    "\n      clientAlias=").append(clientAlias);
         buffer.append(    "\n      server=").append(server);
+        if (serverAlias != null)
+            buffer.append(    "\n      serverAlias=").append(serverAlias);
         if (authTime != null) {
             buffer.append("\n    authTime=").append(authTime);
         }
@@ -531,4 +563,23 @@
         return buffer.toString();
     }
 
+    public sun.security.krb5.internal.ccache.Credentials toCCacheCreds() {
+        return new sun.security.krb5.internal.ccache.Credentials(
+                getClient(), getServer(),
+                getSessionKey(),
+                date2kt(getAuthTime()),
+                date2kt(getStartTime()),
+                date2kt(getEndTime()),
+                date2kt(getRenewTill()),
+                false,
+                flags,
+                new HostAddresses(getClientAddresses()),
+                getAuthzData(),
+                getTicket(),
+                null);
+    }
+
+    private static KerberosTime date2kt(Date d) {
+        return d == null ? null : new KerberosTime(d);
+    }
 }
diff --git a/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java b/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
index 84ca79b..7d1ebd4 100644
--- a/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
+++ b/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
@@ -25,6 +25,7 @@
 
 package sun.security.krb5;
 
+import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.kerberos.KeyTab;
 
@@ -39,6 +40,14 @@
     public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
             KeyTab ktab);
 
+    public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t);
+
+    public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a);
+
+    public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t);
+
+    public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a);
+
     /**
      * Returns the proxy for a KerberosTicket.
      */
diff --git a/src/share/classes/sun/security/krb5/KrbApReq.java b/src/share/classes/sun/security/krb5/KrbApReq.java
index fbd0557..e36aeac 100644
--- a/src/share/classes/sun/security/krb5/KrbApReq.java
+++ b/src/share/classes/sun/security/krb5/KrbApReq.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -361,7 +361,9 @@
         creds = new Credentials(
                                 apReqMessg.ticket,
                                 authenticator.cname,
+                                null,
                                 apReqMessg.ticket.sname,
+                                null,
                                 enc_ticketPart.key,
                                 enc_ticketPart.flags,
                                 enc_ticketPart.authtime,
diff --git a/src/share/classes/sun/security/krb5/KrbAsRep.java b/src/share/classes/sun/security/krb5/KrbAsRep.java
index b03276f..202e86c 100644
--- a/src/share/classes/sun/security/krb5/KrbAsRep.java
+++ b/src/share/classes/sun/security/krb5/KrbAsRep.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -118,7 +118,7 @@
                     "Cannot find key for type/kvno to decrypt AS REP - " +
                     EType.toString(encPartKeyType) + "/" + encPartKvno);
             }
-        decrypt(dkey, asReq);
+        decrypt(dkey, asReq, cname);
     }
 
     /**
@@ -136,7 +136,7 @@
                 password,
                 encPartKeyType,
                 PAData.getSaltAndParams(encPartKeyType, rep.pAData));
-        decrypt(dkey, asReq);
+        decrypt(dkey, asReq, cname);
     }
 
     /**
@@ -144,7 +144,8 @@
      * @param dkey the decryption key to use
      * @param asReq the original AS-REQ sent, used to validate AS-REP
      */
-    private void decrypt(EncryptionKey dkey, KrbAsReq asReq)
+    private void decrypt(EncryptionKey dkey, KrbAsReq asReq,
+            PrincipalName cname)
             throws KrbException, Asn1Exception, IOException {
         byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey,
             KeyUsage.KU_ENC_AS_REP_PART);
@@ -155,12 +156,18 @@
         rep.encKDCRepPart = enc_part;
 
         ASReq req = asReq.getMessage();
-        check(true, req, rep);
+        check(true, req, rep, dkey);
+
+        PrincipalName clientAlias = cname;
+        if (clientAlias.equals(rep.cname))
+            clientAlias = null;
 
         creds = new Credentials(
                                 rep.ticket,
-                                req.reqBody.cname,
+                                rep.cname,
+                                clientAlias,
                                 enc_part.sname,
+                                null, // No server alias expected in a TGT
                                 enc_part.key,
                                 enc_part.flags,
                                 enc_part.authtime,
diff --git a/src/share/classes/sun/security/krb5/KrbAsReq.java b/src/share/classes/sun/security/krb5/KrbAsReq.java
index 8de29b3..19e3ef6 100644
--- a/src/share/classes/sun/security/krb5/KrbAsReq.java
+++ b/src/share/classes/sun/security/krb5/KrbAsReq.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -35,6 +35,8 @@
 import sun.security.krb5.internal.crypto.Nonce;
 import sun.security.krb5.internal.crypto.KeyUsage;
 import java.io.IOException;
+import java.time.Instant;
+import java.util.Arrays;
 
 /**
  * This class encapsulates the KRB-AS-REQ message that the client
@@ -57,14 +59,14 @@
                       KerberosTime till,        // ok, will use
                       KerberosTime rtime,       // ok
                       int[] eTypes,             // NO
-                      HostAddresses addresses   // ok
+                      HostAddresses addresses,  // ok
+                      PAData[] extraPAs         // ok
                       )
             throws KrbException, IOException {
 
         if (options == null) {
             options = new KDCOptions();
         }
-
         // check if they are valid arguments. The optional fields should be
         // consistent with settings in KDCOptions. Mar 17 2000
         if (options.get(KDCOptions.FORWARDED) ||
@@ -82,12 +84,6 @@
         } else {
             if (from != null)  from = null;
         }
-        if (options.get(KDCOptions.RENEWABLE)) {
-            //  if (rtime == null)
-            //          throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-        } else {
-            if (rtime != null)  rtime = null;
-        }
 
         PAData[] paData = null;
         if (pakey != null) {
@@ -99,6 +95,15 @@
             paData[0] = new PAData( Krb5.PA_ENC_TIMESTAMP,
                                     encTs.asn1Encode());
         }
+        if (extraPAs != null && extraPAs.length > 0) {
+            if (paData == null) {
+                paData = new PAData[extraPAs.length];
+            } else {
+                paData = Arrays.copyOf(paData, paData.length + extraPAs.length);
+            }
+            System.arraycopy(extraPAs, 0, paData,
+                    paData.length - extraPAs.length, extraPAs.length);
+        }
 
         if (cname.getRealm() == null) {
             throw new RealmException(Krb5.REALM_NULL,
@@ -109,8 +114,10 @@
             System.out.println(">>> KrbAsReq creating message");
         }
 
+        Config cfg = Config.getInstance();
+
         // check to use addresses in tickets
-        if (addresses == null && Config.getInstance().useAddresses()) {
+        if (addresses == null && cfg.useAddresses()) {
             addresses = HostAddresses.getLocalAddresses();
         }
 
@@ -120,7 +127,26 @@
         }
 
         if (till == null) {
-            till = new KerberosTime(0); // Choose KDC maximum allowed
+            String d = cfg.get("libdefaults", "ticket_lifetime");
+            if (d != null) {
+                till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
+            } else {
+                till = new KerberosTime(0); // Choose KDC maximum allowed
+            }
+        }
+
+        if (rtime == null) {
+            String d = cfg.get("libdefaults", "renew_lifetime");
+            if (d != null) {
+                rtime = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
+            }
+        }
+
+        if (rtime != null) {
+            options.set(KDCOptions.RENEWABLE, true);
+            if (till.greaterThan(rtime)) {
+                rtime = till;
+            }
         }
 
         // enc-authorization-data and additional-tickets never in AS-REQ
diff --git a/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java b/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
index 3c8fb90..445fa19 100644
--- a/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
+++ b/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, 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
@@ -68,6 +68,7 @@
     // Common data for AS-REQ fields
     private KDCOptions options;
     private PrincipalName cname;
+    private PrincipalName refCname; // May be changed by referrals
     private PrincipalName sname;
     private KerberosTime from;
     private KerberosTime till;
@@ -100,6 +101,7 @@
     private void init(PrincipalName cname)
             throws KrbException {
         this.cname = cname;
+        this.refCname = cname;
         state = State.INIT;
     }
 
@@ -224,6 +226,16 @@
         this.options = options;
     }
 
+    public void setTill(KerberosTime till) {
+        checkState(State.INIT, "Cannot specify till");
+        this.till = till;
+    }
+
+    public void setRTime(KerberosTime rtime) {
+        checkState(State.INIT, "Cannot specify rtime");
+        this.rtime = rtime;
+    }
+
     /**
      * Sets or clears target. If cleared, KrbAsReq might choose krbtgt
      * for cname realm
@@ -252,7 +264,9 @@
      * @throws KrbException
      * @throws IOException
      */
-    private KrbAsReq build(EncryptionKey key) throws KrbException, IOException {
+    private KrbAsReq build(EncryptionKey key, ReferralsState referralsState)
+            throws KrbException, IOException {
+        PAData[] extraPAs = null;
         int[] eTypes;
         if (password != null) {
             eTypes = EType.getDefaults("default_tkt_enctypes");
@@ -262,15 +276,24 @@
                     ks);
             for (EncryptionKey k: ks) k.destroy();
         }
+        options = (options == null) ? new KDCOptions() : options;
+        if (referralsState.isEnabled()) {
+            options.set(KDCOptions.CANONICALIZE, true);
+            extraPAs = new PAData[]{ new PAData(Krb5.PA_REQ_ENC_PA_REP,
+                    new byte[]{}) };
+        } else {
+            options.set(KDCOptions.CANONICALIZE, false);
+        }
         return new KrbAsReq(key,
             options,
-            cname,
+            refCname,
             sname,
             from,
             till,
             rtime,
             eTypes,
-            addresses);
+            addresses,
+            extraPAs);
     }
 
     /**
@@ -308,11 +331,15 @@
      */
     private KrbAsReqBuilder send() throws KrbException, IOException {
         boolean preAuthFailedOnce = false;
-        KdcComm comm = new KdcComm(cname.getRealmAsString());
+        KdcComm comm = null;
         EncryptionKey pakey = null;
+        ReferralsState referralsState = new ReferralsState();
         while (true) {
+            if (referralsState.refreshComm()) {
+                comm = new KdcComm(refCname.getRealmAsString());
+            }
             try {
-                req = build(pakey);
+                req = build(pakey, referralsState);
                 rep = new KrbAsRep(comm.send(req.encoding()));
                 return this;
             } catch (KrbException ke) {
@@ -341,12 +368,71 @@
                     }
                     paList = kerr.getPA();  // Update current paList
                 } else {
+                    if (referralsState.handleError(ke)) {
+                        pakey = null;
+                        preAuthFailedOnce = false;
+                        continue;
+                    }
                     throw ke;
                 }
             }
         }
     }
 
+    private final class ReferralsState {
+        private boolean enabled;
+        private int count;
+        private boolean refreshComm;
+
+        ReferralsState() throws KrbException {
+            if (Config.DISABLE_REFERRALS) {
+                if (refCname.getNameType() == PrincipalName.KRB_NT_ENTERPRISE) {
+                    throw new KrbException("NT-ENTERPRISE principals only allowed" +
+                            " when referrals are enabled.");
+                }
+                enabled = false;
+            } else {
+                enabled = true;
+            }
+            refreshComm = true;
+        }
+
+        boolean handleError(KrbException ke) throws RealmException {
+            if (enabled) {
+                if (ke.returnCode() == Krb5.KRB_ERR_WRONG_REALM) {
+                    Realm referredRealm = ke.getError().getClientRealm();
+                    if (req.getMessage().reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
+                            referredRealm != null && referredRealm.toString().length() > 0 &&
+                            count < Config.MAX_REFERRALS) {
+                        refCname = new PrincipalName(refCname.getNameType(),
+                                refCname.getNameStrings(), referredRealm);
+                        refreshComm = true;
+                        count++;
+                        return true;
+                    }
+                }
+                if (count < Config.MAX_REFERRALS &&
+                        refCname.getNameType() != PrincipalName.KRB_NT_ENTERPRISE) {
+                    // Server may raise an error if CANONICALIZE is true.
+                    // Try CANONICALIZE false.
+                    enabled = false;
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        boolean refreshComm() {
+            boolean retRefreshComm = refreshComm;
+            refreshComm = false;
+            return retRefreshComm;
+        }
+
+        boolean isEnabled() {
+            return enabled;
+        }
+    }
+
     /**
      * Performs AS-REQ send and AS-REP receive.
      * Maybe a state is needed here, to divide prepare process and getCreds.
diff --git a/src/share/classes/sun/security/krb5/KrbCred.java b/src/share/classes/sun/security/krb5/KrbCred.java
index e6a4785..0ce26ef 100644
--- a/src/share/classes/sun/security/krb5/KrbCred.java
+++ b/src/share/classes/sun/security/krb5/KrbCred.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -34,6 +34,7 @@
 import sun.security.krb5.internal.*;
 import sun.security.krb5.internal.crypto.KeyUsage;
 import java.io.IOException;
+
 import sun.security.util.DerValue;
 
 /**
@@ -62,7 +63,6 @@
 
         PrincipalName client = tgt.getClient();
         PrincipalName tgService = tgt.getServer();
-        PrincipalName server = serviceTicket.getServer();
         if (!serviceTicket.getClient().equals(client))
             throw new KrbException(Krb5.KRB_ERR_GENERIC,
                                 "Client principal does not match");
@@ -75,14 +75,10 @@
         options.set(KDCOptions.FORWARDED, true);
         options.set(KDCOptions.FORWARDABLE, true);
 
-        HostAddresses sAddrs = null;
-        // XXX Also NT_GSS_KRB5_PRINCIPAL can be a host based principal
-        // GSSName.NT_HOSTBASED_SERVICE should display with KRB_NT_SRV_HST
-        if (server.getNameType() == PrincipalName.KRB_NT_SRV_HST)
-            sAddrs=  new HostAddresses(server);
-
         KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService,
-                                         null, null, null, null, sAddrs, null, null, null);
+                null, null, null, null, null,
+                null,   // No easy way to get addresses right
+                null, null, null);
         credMessg = createMessage(tgsReq.sendAndGetCreds(), key);
 
         obuf = credMessg.asn1Encode();
@@ -94,7 +90,6 @@
         EncryptionKey sessionKey
             = delegatedCreds.getSessionKey();
         PrincipalName princ = delegatedCreds.getClient();
-        Realm realm = princ.getRealm();
         PrincipalName tgService = delegatedCreds.getServer();
 
         KrbCredInfo credInfo = new KrbCredInfo(sessionKey,
@@ -157,7 +152,7 @@
                                + " endtime=" + endtime
                                + "renewTill=" + renewTill);
         }
-        creds = new Credentials(ticket, pname, sname, credInfoKey,
+        creds = new Credentials(ticket, pname, null, sname, null, credInfoKey,
                                 flags, authtime, starttime, endtime, renewTill, caddr);
     }
 
diff --git a/src/share/classes/sun/security/krb5/KrbKdcRep.java b/src/share/classes/sun/security/krb5/KrbKdcRep.java
index 6d79afe..da4a8fa 100644
--- a/src/share/classes/sun/security/krb5/KrbKdcRep.java
+++ b/src/share/classes/sun/security/krb5/KrbKdcRep.java
@@ -31,23 +31,41 @@
 package sun.security.krb5;
 
 import sun.security.krb5.internal.*;
+import sun.security.krb5.internal.crypto.KeyUsage;
+import sun.security.util.DerInputStream;
 
 abstract class KrbKdcRep {
 
     static void check(
                       boolean isAsReq,
                       KDCReq req,
-                      KDCRep rep
+                      KDCRep rep,
+                      EncryptionKey replyKey
                       ) throws KrbApErrException {
 
-        if (isAsReq && !req.reqBody.cname.equals(rep.cname)) {
+        // cname change in AS-REP is allowed only if the client
+        // sent CANONICALIZE and the server supports RFC 6806 - Section 11
+        // FAST scheme (ENC-PA-REP flag).
+        if (isAsReq && !req.reqBody.cname.equals(rep.cname) &&
+                (!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
+                 !rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
             rep.encKDCRepPart.key.destroy();
             throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
         }
 
+        // sname change in TGS-REP is allowed only if client
+        // sent CANONICALIZE and new sname is a referral of
+        // the form krbtgt/TO-REALM.COM@FROM-REALM.COM.
         if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) {
-            rep.encKDCRepPart.key.destroy();
-            throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
+            String[] snameStrings = rep.encKDCRepPart.sname.getNameStrings();
+            if (isAsReq || !req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
+                    snameStrings == null || snameStrings.length != 2 ||
+                    !snameStrings[0].equals(PrincipalName.TGS_DEFAULT_SRV_NAME) ||
+                    !rep.encKDCRepPart.sname.getRealmString().equals(
+                            req.reqBody.sname.getRealmString())) {
+                rep.encKDCRepPart.key.destroy();
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
+            }
         }
 
         if (req.reqBody.getNonce() != rep.encKDCRepPart.nonce) {
@@ -82,49 +100,84 @@
                 !rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {
             throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
         }
-        if ((req.reqBody.from == null) || req.reqBody.from.isZero())
+
+        if ((req.reqBody.from == null) || req.reqBody.from.isZero()) {
             // verify this is allowed
             if ((rep.encKDCRepPart.starttime != null) &&
-                !rep.encKDCRepPart.starttime.inClockSkew()) {
+                    !rep.encKDCRepPart.starttime.inClockSkew()) {
                 rep.encKDCRepPart.key.destroy();
                 throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
             }
+        }
 
-        if ((req.reqBody.from != null) && !req.reqBody.from.isZero())
+        if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) {
             // verify this is allowed
             if ((rep.encKDCRepPart.starttime != null) &&
-                !req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
+                    !req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
                 rep.encKDCRepPart.key.destroy();
                 throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
             }
+        }
 
         if (!req.reqBody.till.isZero() &&
-            rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
+                rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
             rep.encKDCRepPart.key.destroy();
             throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
         }
 
-        if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE))
-            if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero())
-                                // verify this is required
+        // RFC 6806 - Section 11 mechanism check
+        if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP) &&
+                req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+            boolean reqPaReqEncPaRep = false;
+            boolean repPaReqEncPaRepValid = false;
+
+            // PA_REQ_ENC_PA_REP only required for AS requests
+            for (PAData pa : req.pAData) {
+                if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+                    reqPaReqEncPaRep = true;
+                    break;
+                }
+            }
+
+            if (rep.encKDCRepPart.pAData != null) {
+                for (PAData pa : rep.encKDCRepPart.pAData) {
+                    if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+                        try {
+                            Checksum repCksum = new Checksum(
+                                    new DerInputStream(
+                                            pa.getValue()).getDerValue());
+                            // The checksum is inside encKDCRepPart so we don't
+                            // care if it's keyed or not.
+                            repPaReqEncPaRepValid =
+                                    repCksum.verifyAnyChecksum(
+                                            req.asn1Encode(), replyKey,
+                                            KeyUsage.KU_AS_REQ);
+                        } catch (Exception e) {
+                            if (Krb5.DEBUG) {
+                                e.printStackTrace();
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+
+            if (reqPaReqEncPaRep && !repPaReqEncPaRepValid) {
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
+            }
+        }
+
+        if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) {
+            if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) {
+                // verify this is required
                 if ((rep.encKDCRepPart.renewTill == null) ||
-                    rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
-                    ) {
+                        rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
+                        ) {
                     rep.encKDCRepPart.key.destroy();
                     throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
                 }
 
-        if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE_OK) &&
-            rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE))
-            if (!req.reqBody.till.isZero())
-                                // verify this is required
-                if ((rep.encKDCRepPart.renewTill == null) ||
-                    rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.till)
-                    ) {
-                    rep.encKDCRepPart.key.destroy();
-                    throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
-                }
+            }
+        }
     }
-
-
 }
diff --git a/src/share/classes/sun/security/krb5/KrbTgsRep.java b/src/share/classes/sun/security/krb5/KrbTgsRep.java
index 4f5c2d6..83f0b28 100644
--- a/src/share/classes/sun/security/krb5/KrbTgsRep.java
+++ b/src/share/classes/sun/security/krb5/KrbTgsRep.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -84,11 +84,22 @@
         EncTGSRepPart enc_part = new EncTGSRepPart(ref);
         rep.encKDCRepPart = enc_part;
 
-        check(false, req, rep);
+        check(false, req, rep, tgsReq.tgsReqKey);
+
+        PrincipalName serverAlias = tgsReq.getServerAlias();
+        if (serverAlias != null) {
+            PrincipalName repSname = enc_part.sname;
+            if (serverAlias.equals(repSname) ||
+                    isReferralSname(repSname)) {
+                serverAlias = null;
+            }
+        }
 
         this.creds = new Credentials(rep.ticket,
                                 rep.cname,
+                                tgsReq.getClientAlias(),
                                 enc_part.sname,
+                                serverAlias,
                                 enc_part.key,
                                 enc_part.flags,
                                 enc_part.authtime,
@@ -111,4 +122,16 @@
     sun.security.krb5.internal.ccache.Credentials setCredentials() {
         return new sun.security.krb5.internal.ccache.Credentials(rep, secondTicket);
     }
+
+    private static boolean isReferralSname(PrincipalName sname) {
+        if (sname != null) {
+            String[] snameStrings = sname.getNameStrings();
+            if (snameStrings.length == 2 &&
+                    snameStrings[0].equals(
+                            PrincipalName.TGS_DEFAULT_SRV_NAME)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/src/share/classes/sun/security/krb5/KrbTgsReq.java b/src/share/classes/sun/security/krb5/KrbTgsReq.java
index 85b7cb2..151f68b 100644
--- a/src/share/classes/sun/security/krb5/KrbTgsReq.java
+++ b/src/share/classes/sun/security/krb5/KrbTgsReq.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -35,6 +35,7 @@
 import sun.security.krb5.internal.crypto.*;
 import java.io.IOException;
 import java.net.UnknownHostException;
+import java.time.Instant;
 import java.util.Arrays;
 
 /**
@@ -44,7 +45,9 @@
 public class KrbTgsReq {
 
     private PrincipalName princName;
+    private PrincipalName clientAlias;
     private PrincipalName servName;
+    private PrincipalName serverAlias;
     private TGSReq tgsReqMessg;
     private KerberosTime ctime;
     private Ticket secondTicket = null;
@@ -57,59 +60,26 @@
     private byte[] ibuf;
 
     // Used in CredentialsUtil
-    public KrbTgsReq(Credentials asCreds,
-                     PrincipalName sname)
+    public KrbTgsReq(KDCOptions options, Credentials asCreds,
+            PrincipalName cname, PrincipalName clientAlias,
+            PrincipalName sname, PrincipalName serverAlias,
+            Ticket[] additionalTickets, PAData[] extraPAs)
         throws KrbException, IOException {
-        this(new KDCOptions(),
-            asCreds,
-            sname,
-            null, // KerberosTime from
-            null, // KerberosTime till
-            null, // KerberosTime rtime
-            null, // eTypes, // null, // int[] eTypes
-            null, // HostAddresses addresses
-            null, // AuthorizationData authorizationData
-            null, // Ticket[] additionalTickets
-            null); // EncryptionKey subSessionKey
-    }
-
-    // S4U2proxy
-    public KrbTgsReq(Credentials asCreds,
-                     Ticket second,
-                     PrincipalName sname)
-            throws KrbException, IOException {
-        this(KDCOptions.with(KDCOptions.CNAME_IN_ADDL_TKT,
-                KDCOptions.FORWARDABLE),
-            asCreds,
-            sname,
-            null,
-            null,
-            null,
-            null,
-            null,
-            null,
-            new Ticket[] {second}, // the service ticket
-            null);
-    }
-
-    // S4U2user
-    public KrbTgsReq(Credentials asCreds,
-                     PrincipalName sname,
-                     PAData extraPA)
-        throws KrbException, IOException {
-        this(KDCOptions.with(KDCOptions.FORWARDABLE),
-            asCreds,
-            asCreds.getClient(),
-            sname,
-            null,
-            null,
-            null,
-            null,
-            null,
-            null,
-            null,
-            null,
-            extraPA); // the PA-FOR-USER
+        this(options,
+             asCreds,
+             cname,
+             clientAlias,
+             sname,
+             serverAlias,
+             null, // KerberosTime from
+             null, // KerberosTime till
+             null, // KerberosTime rtime
+             null, // int[] eTypes
+             null, // HostAddresses addresses
+             null, // AuthorizationData authorizationData
+             additionalTickets,
+             null, // EncryptionKey subKey
+             extraPAs);
     }
 
     // Called by Credentials, KrbCred
@@ -117,6 +87,7 @@
             KDCOptions options,
             Credentials asCreds,
             PrincipalName sname,
+            PrincipalName serverAlias,
             KerberosTime from,
             KerberosTime till,
             KerberosTime rtime,
@@ -125,16 +96,18 @@
             AuthorizationData authorizationData,
             Ticket[] additionalTickets,
             EncryptionKey subKey) throws KrbException, IOException {
-        this(options, asCreds, asCreds.getClient(), sname,
-                from, till, rtime, eTypes, addresses,
-                authorizationData, additionalTickets, subKey, null);
+        this(options, asCreds, asCreds.getClient(), asCreds.getClientAlias(),
+                sname, serverAlias, from, till, rtime, eTypes,
+                addresses, authorizationData, additionalTickets, subKey, null);
     }
 
     private KrbTgsReq(
             KDCOptions options,
             Credentials asCreds,
             PrincipalName cname,
+            PrincipalName clientAlias,
             PrincipalName sname,
+            PrincipalName serverAlias,
             KerberosTime from,
             KerberosTime till,
             KerberosTime rtime,
@@ -143,10 +116,12 @@
             AuthorizationData authorizationData,
             Ticket[] additionalTickets,
             EncryptionKey subKey,
-            PAData extraPA) throws KrbException, IOException {
+            PAData[] extraPAs) throws KrbException, IOException {
 
         princName = cname;
+        this.clientAlias = clientAlias;
         servName = sname;
+        this.serverAlias = serverAlias;
         ctime = KerberosTime.now();
 
         // check if they are valid arguments. The optional fields
@@ -216,7 +191,7 @@
                 authorizationData,
                 additionalTickets,
                 subKey,
-                extraPA);
+                extraPAs);
         obuf = tgsReqMessg.asn1Encode();
 
         // XXX We need to revisit this to see if can't move it
@@ -282,11 +257,16 @@
                          AuthorizationData authorizationData,
                          Ticket[] additionalTickets,
                          EncryptionKey subKey,
-                         PAData extraPA)
+                         PAData[] extraPAs)
         throws IOException, KrbException, UnknownHostException {
         KerberosTime req_till = null;
         if (till == null) {
-            req_till = new KerberosTime(0);
+            String d = Config.getInstance().get("libdefaults", "ticket_lifetime");
+            if (d != null) {
+                req_till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
+            } else {
+                req_till = new KerberosTime(0); // Choose KDC maximum allowed
+            }
         } else {
             req_till = till;
         }
@@ -340,26 +320,8 @@
         byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ);
         // if the checksum type is one of the keyed checksum types,
         // use session key.
-        Checksum cksum;
-        switch (Checksum.CKSUMTYPE_DEFAULT) {
-        case Checksum.CKSUMTYPE_RSA_MD4_DES:
-        case Checksum.CKSUMTYPE_DES_MAC:
-        case Checksum.CKSUMTYPE_DES_MAC_K:
-        case Checksum.CKSUMTYPE_RSA_MD4_DES_K:
-        case Checksum.CKSUMTYPE_RSA_MD5_DES:
-        case Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD:
-        case Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR:
-        case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128:
-        case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
-            cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
+        Checksum cksum  = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
                 KeyUsage.KU_PA_TGS_REQ_CKSUM);
-            break;
-        case Checksum.CKSUMTYPE_CRC32:
-        case Checksum.CKSUMTYPE_RSA_MD4:
-        case Checksum.CKSUMTYPE_RSA_MD5:
-        default:
-            cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp);
-        }
 
         // Usage will be KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR
 
@@ -375,11 +337,14 @@
                                          null).getMessage();
 
         PAData tgsPAData = new PAData(Krb5.PA_TGS_REQ, tgs_ap_req);
-        return new TGSReq(
-                extraPA != null ?
-                    new PAData[] {extraPA, tgsPAData } :
-                    new PAData[] {tgsPAData},
-                reqBody);
+        PAData[] pa;
+        if (extraPAs != null) {
+            pa = Arrays.copyOf(extraPAs, extraPAs.length + 1);
+            pa[extraPAs.length] = tgsPAData;
+        } else {
+            pa = new PAData[] {tgsPAData};
+        }
+        return new TGSReq(pa, reqBody);
     }
 
     TGSReq getMessage() {
@@ -390,6 +355,14 @@
         return secondTicket;
     }
 
+    PrincipalName getClientAlias() {
+        return clientAlias;
+    }
+
+    PrincipalName getServerAlias() {
+        return serverAlias;
+    }
+
     private static void debug(String message) {
         //      System.err.println(">>> KrbTgsReq: " + message);
     }
diff --git a/src/share/classes/sun/security/krb5/PrincipalName.java b/src/share/classes/sun/security/krb5/PrincipalName.java
index 6d5ed3d..4a16eb3 100644
--- a/src/share/classes/sun/security/krb5/PrincipalName.java
+++ b/src/share/classes/sun/security/krb5/PrincipalName.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -91,6 +91,11 @@
     public static final int KRB_NT_UID = 5;
 
     /**
+     * Enterprise name (alias)
+     */
+    public static final int KRB_NT_ENTERPRISE = 10;
+
+    /**
      * TGS Name
      */
     public static final String TGS_DEFAULT_SRV_NAME = "krbtgt";
@@ -454,6 +459,7 @@
         case KRB_NT_SRV_INST:
         case KRB_NT_SRV_XHST:
         case KRB_NT_UID:
+        case KRB_NT_ENTERPRISE:
             nameStrings = nameParts;
             nameType = type;
             if (realm != null) {
@@ -547,7 +553,9 @@
         for (int i = 0; i < nameStrings.length; i++) {
             if (i > 0)
                 str.append("/");
-            str.append(nameStrings[i]);
+            String n = nameStrings[i];
+            n = n.replace("@", "\\@");
+            str.append(n);
         }
         str.append("@");
         str.append(nameRealm.toString());
diff --git a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
index 14620e9..6cfcd41 100644
--- a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
+++ b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -33,6 +33,8 @@
 
 import sun.security.krb5.*;
 import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * This class is a utility that contains much of the TGS-Exchange
@@ -61,13 +63,11 @@
         if (!ccreds.isForwardable()) {
             throw new KrbException("S4U2self needs a FORWARDABLE ticket");
         }
-        KrbTgsReq req = new KrbTgsReq(
-                ccreds,
-                ccreds.getClient(),
-                new PAData(Krb5.PA_FOR_USER,
-                    new PAForUserEnc(client,
-                        ccreds.getSessionKey()).asn1Encode()));
-        Credentials creds = req.sendAndGetCreds();
+        Credentials creds = serviceCreds(KDCOptions.with(KDCOptions.FORWARDABLE),
+                ccreds, ccreds.getClient(), ccreds.getClient(), null,
+                new PAData[] {new PAData(Krb5.PA_FOR_USER,
+                        new PAForUserEnc(client,
+                            ccreds.getSessionKey()).asn1Encode())});
         if (!creds.getClient().equals(client)) {
             throw new KrbException("S4U2self request not honored by KDC");
         }
@@ -89,11 +89,10 @@
                 String backend, Ticket second,
                 PrincipalName client, Credentials ccreds)
             throws KrbException, IOException {
-        KrbTgsReq req = new KrbTgsReq(
-                ccreds,
-                second,
-                new PrincipalName(backend));
-        Credentials creds = req.sendAndGetCreds();
+        Credentials creds = serviceCreds(KDCOptions.with(
+                KDCOptions.CNAME_IN_ADDL_TKT, KDCOptions.FORWARDABLE),
+                ccreds, ccreds.getClient(), new PrincipalName(backend),
+                new Ticket[] {second}, null);
         if (!creds.getClient().equals(client)) {
             throw new KrbException("S4U2proxy request not honored by KDC");
         }
@@ -114,53 +113,9 @@
     public static Credentials acquireServiceCreds(
                 String service, Credentials ccreds)
             throws KrbException, IOException {
-        PrincipalName sname = new PrincipalName(service);
-        String serviceRealm = sname.getRealmString();
-        String localRealm = ccreds.getClient().getRealmString();
-
-        if (localRealm.equals(serviceRealm)) {
-            if (DEBUG) {
-                System.out.println(
-                        ">>> Credentials acquireServiceCreds: same realm");
-            }
-            return serviceCreds(sname, ccreds);
-        }
-        Credentials theCreds = null;
-
-        boolean[] okAsDelegate = new boolean[1];
-        Credentials theTgt = getTGTforRealm(localRealm, serviceRealm,
-                ccreds, okAsDelegate);
-        if (theTgt != null) {
-            if (DEBUG) {
-                System.out.println(">>> Credentials acquireServiceCreds: "
-                        + "got right tgt");
-                System.out.println(">>> Credentials acquireServiceCreds: "
-                        + "obtaining service creds for " + sname);
-            }
-
-            try {
-                theCreds = serviceCreds(sname, theTgt);
-            } catch (Exception exc) {
-                if (DEBUG) {
-                    System.out.println(exc);
-                }
-                theCreds = null;
-            }
-        }
-
-        if (theCreds != null) {
-            if (DEBUG) {
-                System.out.println(">>> Credentials acquireServiceCreds: "
-                        + "returning creds:");
-                Credentials.printDebug(theCreds);
-            }
-            if (!okAsDelegate[0]) {
-                theCreds.resetDelegate();
-            }
-            return theCreds;
-        }
-        throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
-                                    "No service creds");
+        PrincipalName sname = new PrincipalName(service,
+                PrincipalName.KRB_NT_SRV_HST);
+        return serviceCreds(sname, ccreds);
     }
 
     /**
@@ -305,6 +260,153 @@
     private static Credentials serviceCreds(
             PrincipalName service, Credentials ccreds)
             throws KrbException, IOException {
-        return new KrbTgsReq(ccreds, service).sendAndGetCreds();
+        return serviceCreds(new KDCOptions(), ccreds,
+                ccreds.getClient(), service, null, null);
+    }
+
+    /*
+     * Obtains credentials for a service (TGS).
+     * Cross-realm referrals are handled if enabled. A fallback scheme
+     * without cross-realm referrals supports is used in case of server
+     * error to maintain backward compatibility.
+     */
+    private static Credentials serviceCreds(
+            KDCOptions options, Credentials asCreds,
+            PrincipalName cname, PrincipalName sname,
+            Ticket[] additionalTickets, PAData[] extraPAs)
+            throws KrbException, IOException {
+        if (!Config.DISABLE_REFERRALS) {
+            try {
+                return serviceCredsReferrals(options, asCreds,
+                        cname, sname, additionalTickets, extraPAs);
+            } catch (KrbException e) {
+                // Server may raise an error if CANONICALIZE is true.
+                // Try CANONICALIZE false.
+            }
+        }
+        return serviceCredsSingle(options, asCreds, cname,
+                asCreds.getClientAlias(), sname, sname, additionalTickets,
+                extraPAs);
+    }
+
+    /*
+     * Obtains credentials for a service (TGS).
+     * May handle and follow cross-realm referrals as defined by RFC 6806.
+     */
+    private static Credentials serviceCredsReferrals(
+            KDCOptions options, Credentials asCreds,
+            PrincipalName cname, PrincipalName sname,
+            Ticket[] additionalTickets, PAData[] extraPAs)
+            throws KrbException, IOException {
+        options = new KDCOptions(options.toBooleanArray());
+        options.set(KDCOptions.CANONICALIZE, true);
+        PrincipalName cSname = sname;
+        PrincipalName refSname = sname; // May change with referrals
+        Credentials creds = null;
+        boolean isReferral = false;
+        List<String> referrals = new LinkedList<>();
+        PrincipalName clientAlias = asCreds.getClientAlias();
+        while (referrals.size() <= Config.MAX_REFERRALS) {
+            ReferralsCache.ReferralCacheEntry ref =
+                    ReferralsCache.get(cname, sname, refSname.getRealmString());
+            String toRealm = null;
+            if (ref == null) {
+                creds = serviceCredsSingle(options, asCreds, cname,
+                        clientAlias, refSname, cSname, additionalTickets,
+                        extraPAs);
+                PrincipalName server = creds.getServer();
+                if (!refSname.equals(server)) {
+                    String[] serverNameStrings = server.getNameStrings();
+                    if (serverNameStrings.length == 2 &&
+                        serverNameStrings[0].equals(
+                                PrincipalName.TGS_DEFAULT_SRV_NAME) &&
+                        !refSname.getRealmAsString().equals(serverNameStrings[1])) {
+                        // Server Name (sname) has the following format:
+                        //      krbtgt/TO-REALM.COM@FROM-REALM.COM
+                        ReferralsCache.put(cname, sname, server.getRealmString(),
+                                serverNameStrings[1], creds);
+                        toRealm = serverNameStrings[1];
+                        isReferral = true;
+                        asCreds = creds;
+                    }
+                }
+            } else {
+                toRealm = ref.getToRealm();
+                asCreds = ref.getCreds();
+                isReferral = true;
+            }
+            if (isReferral) {
+                if (referrals.contains(toRealm)) {
+                    // Referrals loop detected
+                    return null;
+                }
+                refSname = new PrincipalName(refSname.getNameString(),
+                        refSname.getNameType(), toRealm);
+                referrals.add(toRealm);
+                isReferral = false;
+                continue;
+            }
+            break;
+        }
+        return creds;
+    }
+
+    /*
+     * Obtains credentials for a service (TGS).
+     * If the service realm is different than the one in the TGT, a new TGT for
+     * the service realm is obtained first (see getTGTforRealm call). This is
+     * not expected when following cross-realm referrals because the referral
+     * TGT realm matches the service realm.
+     */
+    private static Credentials serviceCredsSingle(
+            KDCOptions options, Credentials asCreds,
+            PrincipalName cname, PrincipalName clientAlias,
+            PrincipalName refSname, PrincipalName sname,
+            Ticket[] additionalTickets, PAData[] extraPAs)
+            throws KrbException, IOException {
+        Credentials theCreds = null;
+        boolean[] okAsDelegate = new boolean[]{true};
+        String[] serverAsCredsNames = asCreds.getServer().getNameStrings();
+        String tgtRealm = serverAsCredsNames[1];
+        String serviceRealm = refSname.getRealmString();
+        if (!serviceRealm.equals(tgtRealm)) {
+            // This is a cross-realm service request
+            if (DEBUG) {
+                System.out.println(">>> serviceCredsSingle:" +
+                        " cross-realm authentication");
+                System.out.println(">>> serviceCredsSingle:" +
+                        " obtaining credentials from " + tgtRealm +
+                        " to " + serviceRealm);
+            }
+            Credentials newTgt = getTGTforRealm(tgtRealm, serviceRealm,
+                    asCreds, okAsDelegate);
+            if (newTgt == null) {
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
+                        "No service creds");
+            }
+            if (DEBUG) {
+                System.out.println(">>> Cross-realm TGT Credentials" +
+                        " serviceCredsSingle: ");
+                Credentials.printDebug(newTgt);
+            }
+            asCreds = newTgt;
+            cname = asCreds.getClient();
+        } else if (DEBUG) {
+            System.out.println(">>> Credentials serviceCredsSingle:" +
+                    " same realm");
+        }
+        KrbTgsReq req = new KrbTgsReq(options, asCreds, cname, clientAlias,
+                refSname, sname, additionalTickets, extraPAs);
+        theCreds = req.sendAndGetCreds();
+        if (theCreds != null) {
+            if (DEBUG) {
+                System.out.println(">>> TGS credentials serviceCredsSingle:");
+                Credentials.printDebug(theCreds);
+            }
+            if (!okAsDelegate[0]) {
+                theCreds.resetDelegate();
+            }
+        }
+        return theCreds;
     }
 }
diff --git a/src/share/classes/sun/security/krb5/internal/EncASRepPart.java b/src/share/classes/sun/security/krb5/internal/EncASRepPart.java
index 7e5d037..ff9382e 100644
--- a/src/share/classes/sun/security/krb5/internal/EncASRepPart.java
+++ b/src/share/classes/sun/security/krb5/internal/EncASRepPart.java
@@ -47,7 +47,8 @@
             KerberosTime new_endtime,
             KerberosTime new_renewTill,
             PrincipalName new_sname,
-            HostAddresses new_caddr) {
+            HostAddresses new_caddr,
+            PAData[] new_pAData) {
         super(
                 new_key,
                 new_lastReq,
@@ -60,6 +61,7 @@
                 new_renewTill,
                 new_sname,
                 new_caddr,
+                new_pAData,
                 Krb5.KRB_ENC_AS_REP_PART
                 );
         //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic
diff --git a/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java b/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java
index 2dd4c84..5c60364 100644
--- a/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java
+++ b/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java
@@ -31,7 +31,6 @@
 package sun.security.krb5.internal;
 
 import sun.security.krb5.*;
-import sun.security.krb5.EncryptionKey;
 import sun.security.util.*;
 import java.util.Vector;
 import java.io.IOException;
@@ -41,19 +40,20 @@
  * Implements the ASN.1 EncKDCRepPart type.
  *
  * <xmp>
- * EncKDCRepPart        ::= SEQUENCE {
- *      key             [0] EncryptionKey,
- *      last-req        [1] LastReq,
- *      nonce           [2] UInt32,
- *      key-expiration  [3] KerberosTime OPTIONAL,
- *      flags           [4] TicketFlags,
- *      authtime        [5] KerberosTime,
- *      starttime       [6] KerberosTime OPTIONAL,
- *      endtime         [7] KerberosTime,
- *      renew-till      [8] KerberosTime OPTIONAL,
- *      srealm          [9] Realm,
- *      sname           [10] PrincipalName,
- *      caddr           [11] HostAddresses OPTIONAL
+ * EncKDCRepPart          ::= SEQUENCE {
+ *      key               [0] EncryptionKey,
+ *      last-req          [1] LastReq,
+ *      nonce             [2] UInt32,
+ *      key-expiration    [3] KerberosTime OPTIONAL,
+ *      flags             [4] TicketFlags,
+ *      authtime          [5] KerberosTime,
+ *      starttime         [6] KerberosTime OPTIONAL,
+ *      endtime           [7] KerberosTime,
+ *      renew-till        [8] KerberosTime OPTIONAL,
+ *      srealm            [9] Realm,
+ *      sname             [10] PrincipalName,
+ *      caddr             [11] HostAddresses OPTIONAL,
+ *      encrypted-pa-data [12] SEQUENCE OF PA-DATA OPTIONAL
  * }
  * </xmp>
  *
@@ -76,6 +76,7 @@
     public KerberosTime renewTill; //optional
     public PrincipalName sname;
     public HostAddresses caddr; //optional
+    public PAData[] pAData; //optional
     public int msgType; //not included in sequence
 
     public EncKDCRepPart(
@@ -90,6 +91,7 @@
             KerberosTime new_renewTill,
             PrincipalName new_sname,
             HostAddresses new_caddr,
+            PAData[] new_pAData,
             int new_msgType) {
         key = new_key;
         lastReq = new_lastReq;
@@ -102,6 +104,7 @@
         renewTill = new_renewTill;
         sname = new_sname;
         caddr = new_caddr;
+        pAData = new_pAData;
         msgType = new_msgType;
     }
 
@@ -160,6 +163,9 @@
         if (der.getData().available() > 0) {
             caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true);
         }
+        if (der.getData().available() > 0) {
+            pAData = PAData.parseSequence(der.getData(), (byte) 0x0C, true);
+        }
         // We observe extra data from MSAD
         /*if (der.getData().available() > 0) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
@@ -175,47 +181,58 @@
      */
     public byte[] asn1Encode(int rep_type) throws Asn1Exception,
             IOException {
+        DerOutputStream bytes;
         DerOutputStream temp = new DerOutputStream();
-        DerOutputStream bytes = new DerOutputStream();
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        DerOutputStream out = new DerOutputStream();
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x00), key.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x01), lastReq.asn1Encode());
         temp.putInteger(BigInteger.valueOf(nonce));
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x02), temp);
 
         if (keyExpiration != null) {
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+            out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                     true, (byte) 0x03), keyExpiration.asn1Encode());
         }
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x04), flags.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x05), authtime.asn1Encode());
         if (starttime != null) {
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+            out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                     true, (byte) 0x06), starttime.asn1Encode());
         }
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x07), endtime.asn1Encode());
         if (renewTill != null) {
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+            out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                     true, (byte) 0x08), renewTill.asn1Encode());
         }
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x09), sname.getRealm().asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                 true, (byte) 0x0A), sname.asn1Encode());
         if (caddr != null) {
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+            out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
                     true, (byte) 0x0B), caddr.asn1Encode());
         }
+        if (pAData != null && pAData.length > 0) {
+            temp = new DerOutputStream();
+            for (int i = 0; i < pAData.length; i++) {
+                temp.write(pAData[i].asn1Encode());
+            }
+            bytes = new DerOutputStream();
+            bytes.write(DerValue.tag_SequenceOf, temp);
+            out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x0C), bytes);
+        }
         //should use the rep_type to build the encoding
         //but other implementations do not; it is ignored and
         //the cached msgType is used instead
         temp = new DerOutputStream();
-        temp.write(DerValue.tag_Sequence, bytes);
+        temp.write(DerValue.tag_Sequence, out);
         bytes = new DerOutputStream();
         bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
                 true, (byte) msgType), temp);
diff --git a/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java b/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java
index cdca881..b1f192e 100644
--- a/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java
+++ b/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java
@@ -46,7 +46,8 @@
             KerberosTime new_endtime,
             KerberosTime new_renewTill,
             PrincipalName new_sname,
-            HostAddresses new_caddr) {
+            HostAddresses new_caddr,
+            PAData[] new_pAData) {
         super(
                 new_key,
                 new_lastReq,
@@ -59,6 +60,7 @@
                 new_renewTill,
                 new_sname,
                 new_caddr,
+                new_pAData,
                 Krb5.KRB_ENC_TGS_REP_PART);
     }
 
diff --git a/src/share/classes/sun/security/krb5/internal/HostAddress.java b/src/share/classes/sun/security/krb5/internal/HostAddress.java
index f3d1d87..77e00a0 100644
--- a/src/share/classes/sun/security/krb5/internal/HostAddress.java
+++ b/src/share/classes/sun/security/krb5/internal/HostAddress.java
@@ -39,6 +39,7 @@
 import java.net.Inet6Address;
 import java.net.UnknownHostException;
 import java.io.IOException;
+import java.util.Arrays;
 
 /**
  * Implements the ASN.1 HostAddress type.
@@ -295,4 +296,11 @@
         }
     }
 
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Arrays.toString(address));
+        sb.append('(').append(addrType).append(')');
+        return sb.toString();
+    }
 }
diff --git a/src/share/classes/sun/security/krb5/internal/HostAddresses.java b/src/share/classes/sun/security/krb5/internal/HostAddresses.java
index 8dc9a28..38bb6a3 100644
--- a/src/share/classes/sun/security/krb5/internal/HostAddresses.java
+++ b/src/share/classes/sun/security/krb5/internal/HostAddresses.java
@@ -31,16 +31,14 @@
 
 package sun.security.krb5.internal;
 
+import sun.security.krb5.Config;
 import sun.security.krb5.PrincipalName;
 import sun.security.krb5.KrbException;
 import sun.security.krb5.Asn1Exception;
 import sun.security.util.*;
-import java.util.Vector;
-import java.util.ArrayList;
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
+
+import java.net.*;
+import java.util.*;
 import java.io.IOException;
 import sun.security.krb5.internal.ccache.CCacheOutputStream;
 
@@ -250,6 +248,10 @@
          */
 
     public void writeAddrs(CCacheOutputStream cos) throws IOException {
+        if (addresses == null || addresses.length == 0) {
+            cos.write32(0);
+            return;
+        }
         cos.write32(addresses.length);
         for (int i = 0; i < addresses.length; i++) {
             cos.write16(addresses[i].addrType);
@@ -289,34 +291,35 @@
      */
     public static HostAddresses getLocalAddresses() throws IOException
     {
-        String hostname = null;
-        InetAddress[] inetAddresses = null;
+        Set<InetAddress> all = new LinkedHashSet<>();
         try {
-            InetAddress localHost = InetAddress.getLocalHost();
-            hostname = localHost.getHostName();
-            inetAddresses = InetAddress.getAllByName(hostname);
-            HostAddress[] hAddresses = new HostAddress[inetAddresses.length];
-            for (int i = 0; i < inetAddresses.length; i++)
-                {
-                    hAddresses[i] = new HostAddress(inetAddresses[i]);
-                }
             if (DEBUG) {
-                System.out.println(">>> KrbKdcReq local addresses for "
-                                   + hostname + " are: ");
-
-                for (int i = 0; i < inetAddresses.length; i++) {
-                    System.out.println("\n\t" + inetAddresses[i]);
-                    if (inetAddresses[i] instanceof Inet4Address)
-                        System.out.println("IPv4 address");
-                    if (inetAddresses[i] instanceof Inet6Address)
-                        System.out.println("IPv6 address");
+                System.out.println(">>> KrbKdcReq local addresses are:");
+            }
+            String extra = Config.getInstance().getAll(
+                    "libdefaults", "extra_addresses");
+            if (extra != null) {
+                for (String s: extra.split("\\s+")) {
+                    all.add(InetAddress.getByName(s));
+                    if (DEBUG) {
+                        System.out.println("   extra_addresses: "
+                                + InetAddress.getByName(s));
+                    }
                 }
             }
-            return (new HostAddresses(hAddresses));
+            for (NetworkInterface ni:
+                    Collections.list(NetworkInterface.getNetworkInterfaces())) {
+                if (DEBUG) {
+                    System.out.println("   NetworkInterface " + ni + ":");
+                    System.out.println("      "
+                            + Collections.list(ni.getInetAddresses()));
+                }
+                all.addAll(Collections.list(ni.getInetAddresses()));
+            }
+            return new HostAddresses(all.toArray(new InetAddress[all.size()]));
         } catch (Exception exc) {
             throw new IOException(exc.toString());
         }
-
     }
 
     /**
@@ -335,4 +338,9 @@
         for (int i = 0; i < inetAddresses.length; i++)
             addresses[i] = new HostAddress(inetAddresses[i]);
     }
+
+    @Override
+    public String toString() {
+        return Arrays.toString(addresses);
+    }
 }
diff --git a/src/share/classes/sun/security/krb5/internal/KDCOptions.java b/src/share/classes/sun/security/krb5/internal/KDCOptions.java
index a3d9302..eb1b6f5 100644
--- a/src/share/classes/sun/security/krb5/internal/KDCOptions.java
+++ b/src/share/classes/sun/security/krb5/internal/KDCOptions.java
@@ -140,6 +140,7 @@
     public static final int UNUSED10        = 10;
     public static final int UNUSED11        = 11;
     public static final int CNAME_IN_ADDL_TKT = 14;
+    public static final int CANONICALIZE    = 15;
     public static final int RENEWABLE_OK    = 27;
     public static final int ENC_TKT_IN_SKEY = 28;
     public static final int RENEW           = 30;
@@ -160,7 +161,8 @@
         "UNUSED11",         //11;
         null,null,
         "CNAME_IN_ADDL_TKT",//14;
-        null,null,null,null,null,null,null,null,null,null,null,null,
+        "CANONICALIZE",     //15;
+        null,null,null,null,null,null,null,null,null,null,null,
         "RENEWABLE_OK",     //27;
         "ENC_TKT_IN_SKEY",  //28;
         null,
diff --git a/src/share/classes/sun/security/krb5/internal/KDCReq.java b/src/share/classes/sun/security/krb5/internal/KDCReq.java
index 16591e8..12d4107 100644
--- a/src/share/classes/sun/security/krb5/internal/KDCReq.java
+++ b/src/share/classes/sun/security/krb5/internal/KDCReq.java
@@ -59,9 +59,9 @@
 public class KDCReq {
 
     public KDCReqBody reqBody;
+    public PAData[] pAData = null; //optional
     private int pvno;
     private int msgType;
-    private PAData[] pAData = null; //optional
 
     public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody,
             int req_type) throws IOException {
@@ -144,23 +144,7 @@
         } else {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
-        if ((der.getData().peekByte() & 0x1F) == 0x03) {
-            subDer = der.getData().getDerValue();
-            DerValue subsubDer = subDer.getData().getDerValue();
-            if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-            }
-            Vector<PAData> v = new Vector<>();
-            while (subsubDer.getData().available() > 0) {
-                v.addElement(new PAData(subsubDer.getData().getDerValue()));
-            }
-            if (v.size() > 0) {
-                pAData = new PAData[v.size()];
-                v.copyInto(pAData);
-            }
-        } else {
-            pAData = null;
-        }
+        pAData = PAData.parseSequence(der.getData(), (byte) 0x03, true);
         subDer = der.getData().getDerValue();
         if ((subDer.getTag() & 0x01F) == 0x04) {
             DerValue subsubDer = subDer.getData().getDerValue();
diff --git a/src/share/classes/sun/security/krb5/internal/KRBError.java b/src/share/classes/sun/security/krb5/internal/KRBError.java
index 6569cbc..5b51706 100644
--- a/src/share/classes/sun/security/krb5/internal/KRBError.java
+++ b/src/share/classes/sun/security/krb5/internal/KRBError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -90,6 +90,7 @@
     private KerberosTime sTime;
     private Integer suSec;
     private int errorCode;
+    private Realm crealm; //optional
     private PrincipalName cname; //optional
     private PrincipalName sname;
     private String eText; //optional
@@ -138,6 +139,7 @@
         sTime = new_sTime;
         suSec = new_suSec;
         errorCode = new_errorCode;
+        crealm = new_cname != null ? new_cname.getRealm() : null;
         cname = new_cname;
         sname = new_sname;
         eText = new_eText;
@@ -166,6 +168,7 @@
         sTime = new_sTime;
         suSec = new_suSec;
         errorCode = new_errorCode;
+        crealm = new_cname != null ? new_cname.getRealm() : null;
         cname = new_cname;
         sname = new_sname;
         eText = new_eText;
@@ -262,6 +265,10 @@
         pa = paList.toArray(new PAData[paList.size()]);
     }
 
+    public final Realm getClientRealm() {
+        return crealm;
+    }
+
     public final KerberosTime getServerTime() {
         return sTime;
     }
@@ -349,7 +356,7 @@
             errorCode = subDer.getData().getBigInteger().intValue();
         }
         else  throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-        Realm crealm = Realm.parse(der.getData(), (byte)0x07, true);
+        crealm = Realm.parse(der.getData(), (byte)0x07, true);
         cname = PrincipalName.parse(der.getData(), (byte)0x08, true, crealm);
         Realm realm = Realm.parse(der.getData(), (byte)0x09, false);
         sname = PrincipalName.parse(der.getData(), (byte)0x0A, false, realm);
@@ -393,6 +400,9 @@
             System.out.println("\t suSec is " + suSec);
             System.out.println("\t error code is " + errorCode);
             System.out.println("\t error Message is " + Krb5.getErrorMessage(errorCode));
+            if (crealm != null) {
+                System.out.println("\t crealm is " + crealm.toString());
+            }
             if (cname != null) {
                 System.out.println("\t cname is " + cname.toString());
             }
@@ -442,8 +452,10 @@
         temp.putInteger(BigInteger.valueOf(errorCode));
         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), temp);
 
+        if (crealm != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), crealm.asn1Encode());
+        }
         if (cname != null) {
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), cname.getRealm().asn1Encode());
             bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), cname.asn1Encode());
         }
 
@@ -488,6 +500,7 @@
                 isEqual(sTime, other.sTime) &&
                 isEqual(suSec, other.suSec) &&
                 errorCode == other.errorCode &&
+                isEqual(crealm, other.crealm) &&
                 isEqual(cname, other.cname) &&
                 isEqual(sname, other.sname) &&
                 isEqual(eText, other.eText) &&
@@ -508,6 +521,7 @@
         if (sTime != null) result = 37 * result + sTime.hashCode();
         if (suSec != null) result = 37 * result + suSec.hashCode();
         result = 37 * result + errorCode;
+        if (crealm != null) result = 37 * result + crealm.hashCode();
         if (cname != null) result = 37 * result + cname.hashCode();
         if (sname != null) result = 37 * result + sname.hashCode();
         if (eText != null) result = 37 * result + eText.hashCode();
diff --git a/src/share/classes/sun/security/krb5/internal/KerberosTime.java b/src/share/classes/sun/security/krb5/internal/KerberosTime.java
index 3beaac8..64225c8 100644
--- a/src/share/classes/sun/security/krb5/internal/KerberosTime.java
+++ b/src/share/classes/sun/security/krb5/internal/KerberosTime.java
@@ -38,6 +38,7 @@
 import sun.security.util.DerValue;
 
 import java.io.IOException;
+import java.time.Instant;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.TimeZone;
@@ -129,6 +130,14 @@
     }
 
     /**
+     * Creates a KerberosTime object from an Instant object
+     */
+    public KerberosTime(Instant instant) {
+        this(instant.getEpochSecond()*1000 + instant.getNano()/1000000L,
+                instant.getNano()/1000%1000);
+    }
+
+    /**
      * Creates a KerberosTime object for now. It uses System.nanoTime()
      * to get a more precise time than "new Date()".
      */
diff --git a/src/share/classes/sun/security/krb5/internal/Krb5.java b/src/share/classes/sun/security/krb5/internal/Krb5.java
index 2be21dc..a2e7e3b 100644
--- a/src/share/classes/sun/security/krb5/internal/Krb5.java
+++ b/src/share/classes/sun/security/krb5/internal/Krb5.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -70,6 +70,7 @@
     public static final int TKT_OPTS_PRE_AUTHENT  = 10;
     public static final int TKT_OPTS_HW_AUTHENT   = 11;
     public static final int TKT_OPTS_DELEGATE     = 13;
+    public static final int TKT_OPTS_ENC_PA_REP   = 15;
     public static final int TKT_OPTS_MAX          = 31;
 
     // KDC Options
@@ -163,6 +164,9 @@
     // S4U2user info
     public static final int PA_FOR_USER      = 129;
 
+    // FAST (RFC 6806)
+    public static final int PA_REQ_ENC_PA_REP = 149;
+
     //-------------------------------+-------------
     //authorization data type        |ad-type value
     //-------------------------------+-------------
@@ -265,6 +269,7 @@
     public static final int KRB_ERR_RESPONSE_TOO_BIG     = 52;   //Response too big for UDP, retry with TCP
     public static final int KRB_ERR_GENERIC              = 60;   //Generic error (description in e-text)
     public static final int KRB_ERR_FIELD_TOOLONG        = 61;   //Field is too long for this implementation
+    public static final int KRB_ERR_WRONG_REALM          = 68;   //Wrong realm
     public static final int KRB_CRYPTO_NOT_SUPPORT      = 100;    //Client does not support this crypto type
     public static final int KRB_AP_ERR_NOREALM          = 62;
     public static final int KRB_AP_ERR_GEN_CRED         = 63;
diff --git a/src/share/classes/sun/security/krb5/internal/NetClient.java b/src/share/classes/sun/security/krb5/internal/NetClient.java
index 6224356..ab4fe40 100644
--- a/src/share/classes/sun/security/krb5/internal/NetClient.java
+++ b/src/share/classes/sun/security/krb5/internal/NetClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -103,7 +103,7 @@
         }
 
         try {
-            return IOUtils.readFully(in, len, true);
+            return IOUtils.readExactlyNBytes(in, len);
         } catch (IOException ioe) {
             if (Krb5.DEBUG) {
                 System.out.println(
diff --git a/src/share/classes/sun/security/krb5/internal/PAData.java b/src/share/classes/sun/security/krb5/internal/PAData.java
index f3fdb0b..fd1429a 100644
--- a/src/share/classes/sun/security/krb5/internal/PAData.java
+++ b/src/share/classes/sun/security/krb5/internal/PAData.java
@@ -1,4 +1,6 @@
 /*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -30,10 +32,12 @@
 
 package sun.security.krb5.internal;
 
-import sun.security.krb5.KrbException;
+import sun.security.krb5.internal.crypto.EType;
 import sun.security.util.*;
 import sun.security.krb5.Asn1Exception;
 import java.io.IOException;
+import java.util.Vector;
+
 import sun.security.krb5.internal.util.KerberosString;
 
 /**
@@ -139,6 +143,41 @@
     }
 
     /**
+     * Parse (unmarshal) a PAData from a DER input stream.  This form
+     * parsing might be used when expanding a value which is part of
+     * a constructed sequence and uses explicitly tagged type.
+     *
+     * @exception Asn1Exception if an Asn1Exception occurs.
+     * @param data the Der input stream value, which contains one or more
+     *        marshaled values.
+     * @param explicitTag tag number.
+     * @param optional indicates if this data field is optional.
+     * @return an array of PAData.
+     */
+    public static PAData[] parseSequence(DerInputStream data,
+                                      byte explicitTag, boolean optional)
+        throws Asn1Exception, IOException {
+        if ((optional) &&
+                (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
+                return null;
+        DerValue subDer = data.getDerValue();
+        DerValue subsubDer = subDer.getData().getDerValue();
+        if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        Vector<PAData> v = new Vector<>();
+        while (subsubDer.getData().available() > 0) {
+            v.addElement(new PAData(subsubDer.getData().getDerValue()));
+        }
+        if (v.size() > 0) {
+            PAData[] pas = new PAData[v.size()];
+            v.copyInto(pas);
+            return pas;
+        }
+        return null;
+    }
+
+    /**
      * Gets the preferred etype from the PAData array.
      * 1. ETYPE-INFO2-ENTRY with unknown s2kparams ignored
      * 2. ETYPE-INFO2 preferred to ETYPE-INFO
@@ -169,8 +208,8 @@
             while (d2.data.available() > 0) {
                 DerValue value = d2.data.getDerValue();
                 ETypeInfo2 tmp = new ETypeInfo2(value);
-                if (tmp.getParams() == null) {
-                    // we don't support non-null s2kparams
+                if (EType.isNewer(tmp.getEType()) || tmp.getParams() == null) {
+                    // we don't support non-null s2kparams for old etypes
                     return tmp.getEType();
                 }
             }
@@ -236,8 +275,9 @@
             while (d2.data.available() > 0) {
                 DerValue value = d2.data.getDerValue();
                 ETypeInfo2 tmp = new ETypeInfo2(value);
-                if (tmp.getParams() == null && tmp.getEType() == eType) {
-                    // we don't support non-null s2kparams
+                if (tmp.getEType() == eType &&
+                        (EType.isNewer(eType) || tmp.getParams() == null)) {
+                    // we don't support non-null s2kparams for old etypes
                     return new SaltAndParams(tmp.getSalt(), tmp.getParams());
                 }
             }
diff --git a/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java b/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java
index 42c9caa..a1952ff 100644
--- a/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java
+++ b/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -133,6 +133,7 @@
         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), name.getRealm().asn1Encode());
 
         try {
+            // MS-SFU 2.2.1: use hmac-md5 checksum regardless of key type
             Checksum cks = new Checksum(
                     Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR,
                     getS4UByteArray(),
diff --git a/src/share/classes/sun/security/krb5/internal/ReferralsCache.java b/src/share/classes/sun/security/krb5/internal/ReferralsCache.java
new file mode 100644
index 0000000..970d432
--- /dev/null
+++ b/src/share/classes/sun/security/krb5/internal/ReferralsCache.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.krb5.internal;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import sun.security.krb5.Credentials;
+import sun.security.krb5.PrincipalName;
+
+/*
+ * ReferralsCache class implements a cache scheme for referral TGTs as
+ * described in RFC 6806 - 10. Caching Information. The goal is to optimize
+ * resources (such as network traffic) when a client requests credentials for a
+ * service principal to a given KDC. If a referral TGT was previously received,
+ * cached information is used instead of issuing a new query. Once a referral
+ * TGT expires, the corresponding referral entry in the cache is removed.
+ */
+final class ReferralsCache {
+
+    private static Map<ReferralCacheKey, Map<String, ReferralCacheEntry>>
+            referralsMap = new HashMap<>();
+
+    static private final class ReferralCacheKey {
+        private PrincipalName cname;
+        private PrincipalName sname;
+        ReferralCacheKey (PrincipalName cname, PrincipalName sname) {
+            this.cname = cname;
+            this.sname = sname;
+        }
+        public boolean equals(Object other) {
+            if (!(other instanceof ReferralCacheKey))
+                return false;
+            ReferralCacheKey that = (ReferralCacheKey)other;
+            return cname.equals(that.cname) &&
+                    sname.equals(that.sname);
+        }
+        public int hashCode() {
+            return cname.hashCode() + sname.hashCode();
+        }
+    }
+
+    static final class ReferralCacheEntry {
+        private final Credentials creds;
+        private final String toRealm;
+        ReferralCacheEntry(Credentials creds, String toRealm) {
+            this.creds = creds;
+            this.toRealm = toRealm;
+        }
+        Credentials getCreds() {
+            return creds;
+        }
+        String getToRealm() {
+            return toRealm;
+        }
+    }
+
+    /*
+     * Add a new referral entry to the cache, including: client principal,
+     * service principal, source KDC realm, destination KDC realm and
+     * referral TGT.
+     *
+     * If a loop is generated when adding the new referral, the first hop is
+     * automatically removed. For example, let's assume that adding a
+     * REALM-3.COM -> REALM-1.COM referral generates the following loop:
+     * REALM-1.COM -> REALM-2.COM -> REALM-3.COM -> REALM-1.COM. Then,
+     * REALM-1.COM -> REALM-2.COM referral entry is removed from the cache.
+     */
+    static synchronized void put(PrincipalName cname, PrincipalName service,
+            String fromRealm, String toRealm, Credentials creds) {
+        ReferralCacheKey k = new ReferralCacheKey(cname, service);
+        pruneExpired(k);
+        if (creds.getEndTime().before(new Date())) {
+            return;
+        }
+        Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
+        if (entries == null) {
+            entries = new HashMap<String, ReferralCacheEntry>();
+            referralsMap.put(k, entries);
+        }
+        entries.remove(fromRealm);
+        ReferralCacheEntry newEntry = new ReferralCacheEntry(creds, toRealm);
+        entries.put(fromRealm, newEntry);
+
+        // Remove loops within the cache
+        ReferralCacheEntry current = newEntry;
+        List<ReferralCacheEntry> seen = new LinkedList<>();
+        while (current != null) {
+            if (seen.contains(current)) {
+                // Loop found. Remove the first referral to cut the loop.
+                entries.remove(newEntry.getToRealm());
+                break;
+            }
+            seen.add(current);
+            current = entries.get(current.getToRealm());
+        }
+    }
+
+    /*
+     * Obtain a referral entry from the cache given a client principal,
+     * service principal and a source KDC realm.
+     */
+    static synchronized ReferralCacheEntry get(PrincipalName cname,
+            PrincipalName service, String fromRealm) {
+        ReferralCacheKey k = new ReferralCacheKey(cname, service);
+        pruneExpired(k);
+        Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
+        if (entries != null) {
+            ReferralCacheEntry toRef = entries.get(fromRealm);
+            if (toRef != null) {
+                return toRef;
+            }
+        }
+        return null;
+    }
+
+    /*
+     * Remove referral entries from the cache when referral TGTs expire.
+     */
+    private static void pruneExpired(ReferralCacheKey k) {
+        Date now = new Date();
+        Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
+        if (entries != null) {
+            for (Entry<String, ReferralCacheEntry> mapEntry :
+                    entries.entrySet()) {
+                if (mapEntry.getValue().getCreds().getEndTime().before(now)) {
+                    entries.remove(mapEntry.getKey());
+                }
+            }
+        }
+    }
+}
diff --git a/src/share/classes/sun/security/krb5/internal/TicketFlags.java b/src/share/classes/sun/security/krb5/internal/TicketFlags.java
index 1f77e0f..1b3a182 100644
--- a/src/share/classes/sun/security/krb5/internal/TicketFlags.java
+++ b/src/share/classes/sun/security/krb5/internal/TicketFlags.java
@@ -51,7 +51,8 @@
  *                   renewable(8),
  *                   initial(9),
  *                   pre-authent(10),
- *                   hw-authent(11)
+ *                   hw-authent(11),
+ *                   enc-pa-rep(15)
  *                  }
  */
 public class TicketFlags extends KerberosFlags {
@@ -178,6 +179,9 @@
                 case 11:
                     sb.append("HW-AUTHENT;");
                     break;
+                case 15:
+                    sb.append("ENC-PA-REP;");
+                    break;
                 }
             }
         }
diff --git a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java
index c7d9d2a..a73af46 100644
--- a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java
+++ b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java
@@ -128,7 +128,7 @@
             length--;
         for (int i = 0; i <= length; i++) {
             namelength = readLength4();
-            byte[] bytes = IOUtils.readFully(this, namelength, true);
+            byte[] bytes = IOUtils.readExactlyNBytes(this, namelength);
             result.add(new String(bytes));
         }
         if (result.isEmpty()) {
@@ -186,7 +186,7 @@
         if (version == KRB5_FCC_FVNO_3)
             read(2); /* keytype recorded twice in fvno 3 */
         keyLen = readLength4();
-        byte[] bytes = IOUtils.readFully(this, keyLen, true);
+        byte[] bytes = IOUtils.readExactlyNBytes(this, keyLen);
         return new EncryptionKey(bytes, keyType, new Integer(version));
     }
 
@@ -239,7 +239,7 @@
             for (int i = 0; i < num; i++) {
                 adtype = read(2);
                 adlength = readLength4();
-                data = IOUtils.readFully(this, adlength, true);
+                data = IOUtils.readExactlyNBytes(this, adlength);
                 auData.add(new AuthorizationDataEntry(adtype, data));
             }
             return auData.toArray(new AuthorizationDataEntry[auData.size()]);
@@ -253,7 +253,7 @@
         if (length == 0) {
             return null;
         } else {
-            return IOUtils.readFully(this, length, true);
+            return IOUtils.readExactlyNBytes(this, length);
         }
     }
 
diff --git a/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java b/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java
index c62e629..ccb9b1c 100644
--- a/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java
+++ b/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java
@@ -192,8 +192,9 @@
         // is most likely to be the one in Authenticator in PA-TGS-REQ encoded
         // in TGS-REQ, therefore only stored with a service ticket. Currently
         // in Java, we only reads TGTs.
-        return new sun.security.krb5.Credentials(ticket,
-                cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr);
+        return new sun.security.krb5.Credentials(ticket, cname, null, sname,
+                null, key, flags, authtime, starttime, endtime, renewTill,
+                caddr);
     }
 
     public KerberosTime getStartTime() {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
index 8325692..b7b06a9 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -31,10 +31,7 @@
 
 package sun.security.krb5.internal.crypto;
 
-import sun.security.krb5.Config;
 import sun.security.krb5.Checksum;
-import sun.security.krb5.EncryptedData;
-import sun.security.krb5.KrbException;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
 
@@ -81,6 +78,7 @@
             cksumTypeName =
                 "sun.security.krb5.internal.crypto.HmacSha1Aes128CksumType";
             break;
+
         case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
             cksumType = new HmacSha1Aes256CksumType();
             cksumTypeName =
@@ -117,32 +115,11 @@
         return cksumType;
     }
 
-
-    /**
-     * Returns default checksum type.
-     */
-    public static CksumType getInstance() throws KdcErrException {
-        // this method provided for Kerberos applications.
-        int cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default
-        try {
-            Config c = Config.getInstance();
-            if ((cksumType = (Config.getType(c.get("libdefaults",
-                    "ap_req_checksum_type")))) == - 1) {
-                if ((cksumType = Config.getType(c.get("libdefaults",
-                        "checksum_type"))) == -1) {
-                    cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default
-                }
-            }
-        } catch (KrbException e) {
-        }
-        return getInstance(cksumType);
-    }
-
     public abstract int confounderSize();
 
     public abstract int cksumType();
 
-    public abstract boolean isSafe();
+    public abstract boolean isKeyed();
 
     public abstract int cksumSize();
 
@@ -150,13 +127,12 @@
 
     public abstract int keySize();
 
-    public abstract byte[] calculateChecksum(byte[] data, int size)
-        throws KrbCryptoException;
-
-    public abstract byte[] calculateKeyedChecksum(byte[] data, int size,
+    // Note: key and usage will be ignored for an unkeyed checksum.
+    public abstract byte[] calculateChecksum(byte[] data, int size,
         byte[] key, int usage) throws KrbCryptoException;
 
-    public abstract boolean verifyKeyedChecksum(byte[] data, int size,
+    // Note: key and usage will be ignored for an unkeyed checksum.
+    public abstract boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException;
 
     public static boolean isChecksumEqual(byte[] cksum1, byte[] cksum2) {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java
index b1aa0ab..151e2da 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java
@@ -32,7 +32,6 @@
 
 import sun.security.krb5.*;
 import sun.security.krb5.internal.*;
-import java.util.zip.CRC32;
 
 public class Crc32CksumType extends CksumType {
 
@@ -47,7 +46,7 @@
         return Checksum.CKSUMTYPE_CRC32;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return false;
     }
 
@@ -63,18 +62,15 @@
         return 0;
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
+    public byte[] calculateChecksum(byte[] data, int size,
+            byte[] key, int usage) {
         return crc32.byte2crc32sum_bytes(data, size);
     }
 
-    public byte[] calculateKeyedChecksum(byte[] data, int size,
-                                         byte[] key, int usage) {
-                                             return null;
-                                         }
-
-    public boolean verifyKeyedChecksum(byte[] data, int size,
-                                       byte[] key, byte[] checksum, int usage) {
-        return false;
+    public boolean verifyChecksum(byte[] data, int size,
+            byte[] key, byte[] checksum, int usage) {
+        return CksumType.isChecksumEqual(checksum,
+                crc32.byte2crc32sum_bytes(data));
     }
 
     public static byte[] int2quad(long input) {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java b/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java
index 08d9d55..e930d6a 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java
@@ -53,7 +53,7 @@
     }
 
     public int checksumType() {
-        return Checksum.CKSUMTYPE_CRC32;
+        return Checksum.CKSUMTYPE_RSA_MD5;
     }
 
     public int checksumSize() {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java
index 3c3842f..2e11a20 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java
@@ -49,7 +49,7 @@
         return Checksum.CKSUMTYPE_DES_MAC;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -65,10 +65,6 @@
         return 8;
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +74,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
         byte[] new_data = new byte[size + confounderSize()];
         byte[] conf = Confounder.bytes(confounderSize());
@@ -130,7 +126,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
         byte[] cksum = decryptKeyedChecksum(checksum, key);
 
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java
index 805f931..4f706fb 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java
@@ -48,7 +48,7 @@
         return Checksum.CKSUMTYPE_DES_MAC_K;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -64,10 +64,6 @@
         return 8;
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -77,7 +73,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
         //check for weak keys
         try {
@@ -93,9 +89,9 @@
         return cksum;
     }
 
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
-        byte[] new_cksum = calculateKeyedChecksum(data, data.length, key, usage);
+        byte[] new_cksum = calculateChecksum(data, data.length, key, usage);
         return isChecksumEqual(checksum, new_cksum);
     }
 
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/EType.java b/src/share/classes/sun/security/krb5/internal/crypto/EType.java
index feed5d8..ee59d21 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/EType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/EType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -301,6 +301,26 @@
         return isSupported(eTypeConst, enabledETypes);
     }
 
+    /**
+     * https://tools.ietf.org/html/rfc4120#section-3.1.3:
+     *
+     *                 A "newer" enctype is any enctype first officially
+     * specified concurrently with or subsequent to the issue of this RFC.
+     * The enctypes DES, 3DES, or RC4 and any defined in [RFC1510] are not
+     * "newer" enctypes.
+     *
+     * @param eTypeConst the encryption type
+     * @return true if "newer"
+     */
+    public static boolean isNewer(int eTypeConst) {
+        return eTypeConst != EncryptedData.ETYPE_DES_CBC_CRC &&
+                eTypeConst != EncryptedData.ETYPE_DES_CBC_MD4 &&
+                eTypeConst != EncryptedData.ETYPE_DES_CBC_MD5 &&
+                eTypeConst != EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD &&
+                eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC &&
+                eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC_EXP;
+    }
+
     public static String toString(int type) {
         switch (type) {
         case 0:
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java
index 4a233dd..41388ec 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 /**
@@ -51,7 +49,7 @@
         return Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -67,10 +65,6 @@
         return 16;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -98,7 +92,7 @@
      * @param checksum
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java
index ba31b57..a16941c 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 /*
@@ -51,7 +49,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -67,10 +65,6 @@
         return 16;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -98,7 +92,7 @@
      * @param checksum
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java
index d9f213b..9ce9347 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 /*
@@ -51,7 +49,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -67,10 +65,6 @@
         return 32;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -98,7 +92,7 @@
      * @param checksum
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java
index 9547ea0..81e4420 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 public class HmacSha1Des3KdCksumType extends CksumType {
@@ -45,7 +43,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -61,10 +59,6 @@
         return 24;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -72,7 +66,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -92,7 +86,7 @@
      * @param checksum
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java b/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java
index f9be46c..5179f52 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -56,6 +56,7 @@
     public static final int KU_KRB_SAFE_CKSUM = 15;             // KrbSafe
     public static final int KU_PA_FOR_USER_ENC_CKSUM = 17;      // S4U2user
     public static final int KU_AD_KDC_ISSUED_CKSUM = 19;
+    public static final int KU_AS_REQ = 56;
 
     public static final boolean isValid(int usage) {
         return usage >= 0;
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
index c475749..e0c4429 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
@@ -33,8 +33,6 @@
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
 import java.security.MessageDigest;
-import java.security.Provider;
-import java.security.Security;
 
 public final class RsaMd5CksumType extends CksumType {
 
@@ -49,7 +47,7 @@
         return Checksum.CKSUMTYPE_RSA_MD5;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return false;
     }
 
@@ -74,7 +72,8 @@
      * @modified by Yanni Zhang, 12/08/99.
      */
 
-    public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{
+    public byte[] calculateChecksum(byte[] data, int size,
+            byte[] key, int usage) throws KrbCryptoException{
         MessageDigest md5;
         byte[] result = null;
         try {
@@ -91,14 +90,15 @@
         return result;
     }
 
-    public byte[] calculateKeyedChecksum(byte[] data, int size,
-        byte[] key, int usage) throws KrbCryptoException {
-                                             return null;
-                                         }
-
-    public boolean verifyKeyedChecksum(byte[] data, int size,
-        byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
-        return false;
+    @Override
+    public boolean verifyChecksum(byte[] data, int size,
+            byte[] key, byte[] checksum, int usage)
+            throws KrbCryptoException {
+        try {
+            byte[] calculated = MessageDigest.getInstance("MD5").digest(data);
+            return CksumType.isChecksumEqual(calculated, checksum);
+        } catch (Exception e) {
+            return false;
+        }
     }
-
 }
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java
index c4c5383..0d55aed 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java
@@ -33,12 +33,8 @@
 import sun.security.krb5.Confounder;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
 import javax.crypto.spec.DESKeySpec;
 import java.security.MessageDigest;
-import java.security.Provider;
-import java.security.Security;
 import java.security.InvalidKeyException;
 
 public final class RsaMd5DesCksumType extends CksumType {
@@ -54,7 +50,7 @@
         return Checksum.CKSUMTYPE_RSA_MD5_DES;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -79,7 +75,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
         //prepend confounder
         byte[] new_data = new byte[size + confounderSize()];
@@ -88,7 +84,7 @@
         System.arraycopy(data, 0, new_data, confounderSize(), size);
 
         //calculate md5 cksum
-        byte[] mdc_cksum = calculateChecksum(new_data, new_data.length);
+        byte[] mdc_cksum = calculateRawChecksum(new_data, new_data.length);
         byte[] cksum = new byte[cksumSize()];
         System.arraycopy(conf, 0, cksum, 0, confounderSize());
         System.arraycopy(mdc_cksum, 0, cksum, confounderSize(),
@@ -125,7 +121,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
         //decrypt checksum
         byte[] cksum = decryptKeyedChecksum(checksum, key);
@@ -135,7 +131,7 @@
         System.arraycopy(cksum, 0, new_data, 0, confounderSize());
         System.arraycopy(data, 0, new_data, confounderSize(), size);
 
-        byte[] new_cksum = calculateChecksum(new_data, new_data.length);
+        byte[] new_cksum = calculateRawChecksum(new_data, new_data.length);
         //extract original cksum value
         byte[] orig_cksum = new byte[cksumSize() - confounderSize()];
         System.arraycopy(cksum,  confounderSize(), orig_cksum, 0,
@@ -181,7 +177,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{
+    private byte[] calculateRawChecksum(byte[] data, int size) throws KrbCryptoException{
         MessageDigest md5;
         byte[] result = null;
         try {
@@ -197,5 +193,4 @@
         }
         return result;
     }
-
 }
diff --git a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
index 30c9489..07d8e98 100644
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
+++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
@@ -982,7 +982,7 @@
             new CertEntry((X509Certificate) cert, null, alias, AnyUsage,
                 attributes);
         certificateCount++;
-        entries.put(alias, certEntry);
+        entries.put(alias.toLowerCase(Locale.ENGLISH), certEntry);
 
         if (debug != null) {
             debug.println("Setting a trusted certificate at alias '" + alias +
diff --git a/src/share/classes/sun/security/provider/JavaKeyStore.java b/src/share/classes/sun/security/provider/JavaKeyStore.java
index 409af47..6befb54 100644
--- a/src/share/classes/sun/security/provider/JavaKeyStore.java
+++ b/src/share/classes/sun/security/provider/JavaKeyStore.java
@@ -691,7 +691,7 @@
 
                     // Read the private key
                     entry.protectedPrivKey =
-                            IOUtils.readFully(dis, dis.readInt(), true);
+                            IOUtils.readExactlyNBytes(dis, dis.readInt());
 
                     // Read the certificate chain
                     int numOfCerts = dis.readInt();
@@ -716,7 +716,7 @@
                                 }
                             }
                             // instantiate the certificate
-                            encoded = IOUtils.readFully(dis, dis.readInt(), true);
+                            encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                             bais = new ByteArrayInputStream(encoded);
                             certs.add(cf.generateCertificate(bais));
                             bais.close();
@@ -755,7 +755,7 @@
                             cfs.put(certType, cf);
                         }
                     }
-                    encoded = IOUtils.readFully(dis, dis.readInt(), true);
+                    encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                     bais = new ByteArrayInputStream(encoded);
                     entry.cert = cf.generateCertificate(bais);
                     bais.close();
@@ -776,16 +776,13 @@
             if (password != null) {
                 byte computed[], actual[];
                 computed = md.digest();
-                actual = new byte[computed.length];
-                dis.readFully(actual);
-                for (int i = 0; i < computed.length; i++) {
-                    if (computed[i] != actual[i]) {
-                        Throwable t = new UnrecoverableKeyException
+                actual = IOUtils.readExactlyNBytes(dis, computed.length);
+                if (!MessageDigest.isEqual(computed, actual)) {
+                    Throwable t = new UnrecoverableKeyException
                             ("Password verification failed");
-                        throw (IOException)new IOException
+                    throw (IOException) new IOException
                             ("Keystore was tampered with, or "
-                            + "password was incorrect").initCause(t);
-                    }
+                                    + "password was incorrect").initCause(t);
                 }
             }
         }
diff --git a/src/share/classes/sun/security/provider/SunEntries.java b/src/share/classes/sun/security/provider/SunEntries.java
index 008fea5..0ec9813 100644
--- a/src/share/classes/sun/security/provider/SunEntries.java
+++ b/src/share/classes/sun/security/provider/SunEntries.java
@@ -65,7 +65,7 @@
  *   and CRLs. Aliases for X.509 are X509.
  *
  * - PKIX is the certification path validation algorithm described
- *   in RFC 3280. The ValidationAlgorithm attribute notes the
+ *   in RFC 5280. The ValidationAlgorithm attribute notes the
  *   specification that this provider implements.
  *
  * - LDAP is the CertStore type for LDAP repositories. The
@@ -257,7 +257,7 @@
         map.put("CertPathBuilder.PKIX",
             "sun.security.provider.certpath.SunCertPathBuilder");
         map.put("CertPathBuilder.PKIX ValidationAlgorithm",
-            "RFC3280");
+            "RFC5280");
 
         /*
          * CertPathValidator
@@ -265,7 +265,7 @@
         map.put("CertPathValidator.PKIX",
             "sun.security.provider.certpath.PKIXCertPathValidator");
         map.put("CertPathValidator.PKIX ValidationAlgorithm",
-            "RFC3280");
+            "RFC5280");
 
         /*
          * CertStores
diff --git a/src/share/classes/sun/security/provider/certpath/PolicyChecker.java b/src/share/classes/sun/security/provider/certpath/PolicyChecker.java
index ab82820..dd030d3 100644
--- a/src/share/classes/sun/security/provider/certpath/PolicyChecker.java
+++ b/src/share/classes/sun/security/provider/certpath/PolicyChecker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -578,7 +578,7 @@
     }
 
     /**
-     * Rewrite leaf nodes at the end of validation as described in RFC 3280
+     * Rewrite leaf nodes at the end of validation as described in RFC 5280
      * section 6.1.5: Step (g)(iii). Leaf nodes with anyPolicy are replaced
      * by nodes explicitly representing initial policies not already
      * represented by leaf nodes.
diff --git a/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java b/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java
index 02109d4..a42a1e8 100644
--- a/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java
+++ b/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -56,7 +56,7 @@
     private PolicyNodeImpl mParent;
     private HashSet<PolicyNodeImpl> mChildren;
 
-    // the 4 fields specified by RFC 3280
+    // the 4 fields specified by RFC 5280
     private String mValidPolicy;
     private HashSet<PolicyQualifierInfo> mQualifierSet;
     private boolean mCriticalityIndicator;
diff --git a/src/share/classes/sun/security/timestamp/HttpTimestamper.java b/src/share/classes/sun/security/timestamp/HttpTimestamper.java
index 50cef6e..9b646f7 100644
--- a/src/share/classes/sun/security/timestamp/HttpTimestamper.java
+++ b/src/share/classes/sun/security/timestamp/HttpTimestamper.java
@@ -27,6 +27,7 @@
 
 import java.io.BufferedInputStream;
 import java.io.DataOutputStream;
+import java.io.EOFException;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URL;
@@ -147,8 +148,11 @@
             }
             verifyMimeType(connection.getContentType());
 
-            int contentLength = connection.getContentLength();
-            replyBuffer = IOUtils.readFully(input, contentLength, false);
+            int clen = connection.getContentLength();
+            replyBuffer = IOUtils.readAllBytes(input);
+            if (clen != -1 && replyBuffer.length != clen)
+                throw new EOFException("Expected:" + clen +
+                                       ", read:" + replyBuffer.length);
 
             if (debug != null) {
                 debug.println("received timestamp response (length=" +
diff --git a/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java b/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
index 0b97cee..fa05a0d 100644
--- a/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
+++ b/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
@@ -144,7 +144,7 @@
 
     /**
      * Examine the certificate for a Subject Information Access extension
-     * (<a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280</a>).
+     * (<a href="http://tools.ietf.org/html/rfc5280">RFC 5280</a>).
      * The extension's {@code accessMethod} field should contain the object
      * identifier defined for timestamping: 1.3.6.1.5.5.7.48.3 and its
      * {@code accessLocation} field should contain an HTTP or HTTPS URL.
diff --git a/src/share/classes/sun/security/util/DerInputBuffer.java b/src/share/classes/sun/security/util/DerInputBuffer.java
index b09b7b3..54eade3 100644
--- a/src/share/classes/sun/security/util/DerInputBuffer.java
+++ b/src/share/classes/sun/security/util/DerInputBuffer.java
@@ -300,7 +300,7 @@
          *       YYMMDDhhmmss-hhmm
          * UTC Time is broken in storing only two digits of year.
          * If YY < 50, we assume 20YY;
-         * if YY >= 50, we assume 19YY, as per RFC 3280.
+         * if YY >= 50, we assume 19YY, as per RFC 5280.
          *
          * Generalized time has a four-digit year and allows any
          * precision specified in ISO 8601. However, for our purposes,
diff --git a/src/share/classes/sun/security/util/DerOutputStream.java b/src/share/classes/sun/security/util/DerOutputStream.java
index c517df8..05a7b63 100644
--- a/src/share/classes/sun/security/util/DerOutputStream.java
+++ b/src/share/classes/sun/security/util/DerOutputStream.java
@@ -461,7 +461,7 @@
      * Marshals a DER UTC time/date value.
      *
      * <P>YYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time
-     * and with seconds (even if seconds=0) as per RFC 3280.
+     * and with seconds (even if seconds=0) as per RFC 5280.
      */
     public void putUTCTime(Date d) throws IOException {
         putTime(d, DerValue.tag_UtcTime);
@@ -471,7 +471,7 @@
      * Marshals a DER Generalized Time/date value.
      *
      * <P>YYYYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time
-     * and with seconds (even if seconds=0) as per RFC 3280.
+     * and with seconds (even if seconds=0) as per RFC 5280.
      */
     public void putGeneralizedTime(Date d) throws IOException {
         putTime(d, DerValue.tag_GeneralizedTime);
diff --git a/src/share/classes/sun/security/util/DerValue.java b/src/share/classes/sun/security/util/DerValue.java
index 46dcbd3..9372537 100644
--- a/src/share/classes/sun/security/util/DerValue.java
+++ b/src/share/classes/sun/security/util/DerValue.java
@@ -45,8 +45,8 @@
  * (such as PKCS #10 certificate requests, and some kinds of PKCS #7 data).
  *
  * A note with respect to T61/Teletex strings: From RFC 1617, section 4.1.3
- * and RFC 3280, section 4.1.2.4., we assume that this kind of string will
- * contain ISO-8859-1 characters only.
+ * and RFC 5280, section 8, we assume that this kind of string will contain
+ * ISO-8859-1 characters only.
  *
  *
  * @author David Brownell
@@ -409,7 +409,7 @@
         if (fullyBuffered && in.available() != length)
             throw new IOException("extra data given to DerValue constructor");
 
-        byte[] bytes = IOUtils.readFully(in, length, true);
+        byte[] bytes = IOUtils.readExactlyNBytes(in, length);
 
         buffer = new DerInputBuffer(bytes, allowBER);
         return new DerInputStream(buffer);
diff --git a/src/share/classes/sun/security/validator/PKIXValidator.java b/src/share/classes/sun/security/validator/PKIXValidator.java
index 9be5026..d6d973c 100644
--- a/src/share/classes/sun/security/validator/PKIXValidator.java
+++ b/src/share/classes/sun/security/validator/PKIXValidator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -32,6 +32,7 @@
 
 import javax.security.auth.x500.X500Principal;
 import sun.security.action.GetBooleanAction;
+import sun.security.action.GetPropertyAction;
 import sun.security.provider.certpath.AlgorithmChecker;
 import sun.security.provider.certpath.PKIXExtendedParameters;
 
@@ -64,6 +65,18 @@
     // enable use of the validator if possible
     private final static boolean TRY_VALIDATOR = true;
 
+    /**
+     * System property that if set (or set to "true"), allows trust anchor
+     * certificates to be used if they do not have the proper CA extensions.
+     * Set to false if prop is not set, or set to any other value.
+     */
+    private static final boolean ALLOW_NON_CA_ANCHOR = allowNonCaAnchor();
+    private static boolean allowNonCaAnchor() {
+        String prop = GetPropertyAction
+            .privilegedGetProperty("jdk.security.allowNonCaAnchor");
+        return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true"));
+    }
+
     private final Set<X509Certificate> trustedCerts;
     private final PKIXBuilderParameters parameterTemplate;
     private int certPathLength = -1;
@@ -209,6 +222,7 @@
                 ("null or zero-length certificate chain");
         }
 
+
         // Use PKIXExtendedParameters for timestamp and variant additions
         PKIXBuilderParameters pkixParameters = null;
         try {
@@ -234,29 +248,30 @@
             for (int i = 0; i < chain.length; i++) {
                 X509Certificate cert = chain[i];
                 X500Principal dn = cert.getSubjectX500Principal();
-                if (i != 0 &&
-                    !dn.equals(prevIssuer)) {
-                    // chain is not ordered correctly, call builder instead
-                    return doBuild(chain, otherCerts, pkixParameters);
-                }
 
-                // Check if chain[i] is already trusted. It may be inside
-                // trustedCerts, or has the same dn and public key as a cert
-                // inside trustedCerts. The latter happens when a CA has
-                // updated its cert with a stronger signature algorithm in JRE
-                // but the weak one is still in circulation.
-
-                if (trustedCerts.contains(cert) ||          // trusted cert
-                        (trustedSubjects.containsKey(dn) && // replacing ...
-                         trustedSubjects.get(dn).contains(  // ... weak cert
-                            cert.getPublicKey()))) {
-                    if (i == 0) {
+                if (i == 0) {
+                    if (trustedCerts.contains(cert)) {
                         return new X509Certificate[] {chain[0]};
                     }
-                    // Remove and call validator on partial chain [0 .. i-1]
-                    X509Certificate[] newChain = new X509Certificate[i];
-                    System.arraycopy(chain, 0, newChain, 0, i);
-                    return doValidate(newChain, pkixParameters);
+                } else {
+                    if (!dn.equals(prevIssuer)) {
+                        // chain is not ordered correctly, call builder instead
+                        return doBuild(chain, otherCerts, pkixParameters);
+                    }
+                    // Check if chain[i] is already trusted. It may be inside
+                    // trustedCerts, or has the same dn and public key as a cert
+                    // inside trustedCerts. The latter happens when a CA has
+                    // updated its cert with a stronger signature algorithm in JRE
+                    // but the weak one is still in circulation.
+                    if (trustedCerts.contains(cert) ||          // trusted cert
+                            (trustedSubjects.containsKey(dn) && // replacing ...
+                             trustedSubjects.get(dn).contains(  // ... weak cert
+                                cert.getPublicKey()))) {
+                        // Remove and call validator on partial chain [0 .. i-1]
+                        X509Certificate[] newChain = new X509Certificate[i];
+                        System.arraycopy(chain, 0, newChain, 0, i);
+                        return doValidate(newChain, pkixParameters);
+                    }
                 }
                 prevIssuer = cert.getIssuerX500Principal();
             }
@@ -320,15 +335,18 @@
 
     private static X509Certificate[] toArray(CertPath path, TrustAnchor anchor)
             throws CertificateException {
-        List<? extends java.security.cert.Certificate> list =
-                                                path.getCertificates();
-        X509Certificate[] chain = new X509Certificate[list.size() + 1];
-        list.toArray(chain);
         X509Certificate trustedCert = anchor.getTrustedCert();
         if (trustedCert == null) {
             throw new ValidatorException
                 ("TrustAnchor must be specified as certificate");
         }
+
+        verifyTrustAnchor(trustedCert);
+
+        List<? extends java.security.cert.Certificate> list =
+                                                path.getCertificates();
+        X509Certificate[] chain = new X509Certificate[list.size() + 1];
+        list.toArray(chain);
         chain[chain.length - 1] = trustedCert;
         return chain;
     }
@@ -363,6 +381,41 @@
         }
     }
 
+    /**
+     * Verify that a trust anchor certificate is a CA certificate.
+     */
+    private static void verifyTrustAnchor(X509Certificate trustedCert)
+        throws ValidatorException {
+
+        // skip check if jdk.security.allowNonCAAnchor system property is set
+        if (ALLOW_NON_CA_ANCHOR) {
+            return;
+        }
+
+        // allow v1 trust anchor certificates
+        if (trustedCert.getVersion() < 3) {
+            return;
+        }
+
+        // check that the BasicConstraints cA field is not set to false
+        if (trustedCert.getBasicConstraints() == -1) {
+            throw new ValidatorException
+                ("TrustAnchor with subject \"" +
+                 trustedCert.getSubjectX500Principal() +
+                 "\" is not a CA certificate");
+        }
+
+        // check that the KeyUsage extension, if included, asserts the
+        // keyCertSign bit
+        boolean[] keyUsageBits = trustedCert.getKeyUsage();
+        if (keyUsageBits != null && !keyUsageBits[5]) {
+            throw new ValidatorException
+                ("TrustAnchor with subject \"" +
+                 trustedCert.getSubjectX500Principal() +
+                 "\" does not have keyCertSign bit set in KeyUsage extension");
+        }
+    }
+
     private X509Certificate[] doBuild(X509Certificate[] chain,
         Collection<X509Certificate> otherCerts,
         PKIXBuilderParameters params) throws CertificateException {
diff --git a/src/share/classes/sun/security/x509/AVA.java b/src/share/classes/sun/security/x509/AVA.java
index b07e565..8665745 100644
--- a/src/share/classes/sun/security/x509/AVA.java
+++ b/src/share/classes/sun/security/x509/AVA.java
@@ -599,7 +599,7 @@
         if (derval.tag != DerValue.tag_Sequence) {
             throw new IOException("AVA not a sequence");
         }
-        oid = X500Name.intern(derval.data.getOID());
+        oid = derval.data.getOID();
         value = derval.data.getDerValue();
 
         if (derval.data.available() != 0) {
diff --git a/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java b/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
index 725c753..afc642d 100644
--- a/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
+++ b/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -43,7 +43,7 @@
  * certificate that identifies the specific OCSP Responder to use when
  * performing on-line validation of that certificate.
  * <p>
- * This extension is defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
+ * This extension is defined in <a href="http://tools.ietf.org/html/rfc5280">
  * Internet X.509 PKI Certificate and Certificate Revocation List
  * (CRL) Profile</a>. The profile permits
  * the extension to be included in end-entity or CA certificates,
diff --git a/src/share/classes/sun/security/x509/CertificateIssuerExtension.java b/src/share/classes/sun/security/x509/CertificateIssuerExtension.java
index b773970..0dd8f39 100644
--- a/src/share/classes/sun/security/x509/CertificateIssuerExtension.java
+++ b/src/share/classes/sun/security/x509/CertificateIssuerExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -44,7 +44,7 @@
  * <p>
  * If used by conforming CRL issuers, this extension is always
  * critical.  If an implementation ignored this extension it could not
- * correctly attribute CRL entries to certificates.  PKIX (RFC 3280)
+ * correctly attribute CRL entries to certificates.  PKIX (RFC 5280)
  * RECOMMENDS that implementations recognize this extension.
  * <p>
  * The ASN.1 definition for this is:
diff --git a/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java b/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java
index 69be145..4b03223 100644
--- a/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java
+++ b/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -45,7 +45,7 @@
  *
  * <p>
  * The extension is defined in Section 5.2.4 of
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certific
+ * <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
 ate and Certificate Revocation List (CRL) Profile</a>.
  *
  * <p>
diff --git a/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java b/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java
index 6808460..dc82077 100644
--- a/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java
+++ b/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -94,7 +94,7 @@
     public static final String NAME = "ExtendedKeyUsage";
     public static final String USAGES = "usages";
 
-    // OID defined in RFC 3280 Sections 4.2.1.13
+    // OID defined in RFC 5280 Sections 4.2.1.12
     // more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html
     private static final Map <ObjectIdentifier, String> map =
             new HashMap <ObjectIdentifier, String> ();
diff --git a/src/share/classes/sun/security/x509/FreshestCRLExtension.java b/src/share/classes/sun/security/x509/FreshestCRLExtension.java
index 775e2ac..3d0723d 100644
--- a/src/share/classes/sun/security/x509/FreshestCRLExtension.java
+++ b/src/share/classes/sun/security/x509/FreshestCRLExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -42,7 +42,7 @@
  *
  * <p>
  * The extension is defined in Section 5.2.6 of
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certific
+ * <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
 ate and Certificate Revocation List (CRL) Profile</a>.
  *
  * <p>
diff --git a/src/share/classes/sun/security/x509/InvalidityDateExtension.java b/src/share/classes/sun/security/x509/InvalidityDateExtension.java
index eda0216..7fac65f 100644
--- a/src/share/classes/sun/security/x509/InvalidityDateExtension.java
+++ b/src/share/classes/sun/security/x509/InvalidityDateExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -33,7 +33,7 @@
 import sun.security.util.*;
 
 /**
- * From RFC 3280:
+ * From RFC 5280:
  * <p>
  * The invalidity date is a non-critical CRL entry extension that
  * provides the date on which it is known or suspected that the private
diff --git a/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java b/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java
index 6fe8eb3..6866af0 100644
--- a/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java
+++ b/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -46,7 +46,7 @@
  *
  * <p>
  * The extension is defined in Section 5.2.5 of
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certific
+ * <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
 ate and Certificate Revocation List (CRL) Profile</a>.
  *
  * <p>
diff --git a/src/share/classes/sun/security/x509/RDN.java b/src/share/classes/sun/security/x509/RDN.java
index e60e2e8..9eb6068 100644
--- a/src/share/classes/sun/security/x509/RDN.java
+++ b/src/share/classes/sun/security/x509/RDN.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -343,7 +343,7 @@
     /*
      * Returns a printable form of this RDN, using RFC 1779 style catenation
      * of attribute/value assertions, and emitting attribute type keywords
-     * from RFCs 1779, 2253, and 3280.
+     * from RFCs 1779, 2253, and 5280.
      */
     public String toString() {
         if (assertion.length == 1) {
diff --git a/src/share/classes/sun/security/x509/README b/src/share/classes/sun/security/x509/README
index 31a1291..f18a373 100644
--- a/src/share/classes/sun/security/x509/README
+++ b/src/share/classes/sun/security/x509/README
@@ -34,7 +34,7 @@
     Protocol (LDAP) that many organizations are expecting will help
     address online certificate distribution over the Internet.
 
-    RFC 3280, which describes the Internet X.509 Public Key
+    RFC 5280, which describes the Internet X.509 Public Key
     Infrastructure Certificate and CRL Profile.  
 
     RSA DSI has a bunch of "Public Key Cryptography Standards" (PKCS) which
diff --git a/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java b/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
index e1a0bc2..29d60ef 100644
--- a/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
+++ b/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -48,7 +48,7 @@
  * included in end entity or CA certificates.  Conforming CAs MUST mark
  * this extension as non-critical.
  * <p>
- * This extension is defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
+ * This extension is defined in <a href="http://tools.ietf.org/html/rfc5280">
  * Internet X.509 PKI Certificate and Certificate Revocation List
  * (CRL) Profile</a>. The profile permits
  * the extension to be included in end-entity or CA certificates,
diff --git a/src/share/classes/sun/security/x509/URIName.java b/src/share/classes/sun/security/x509/URIName.java
index 3c5b523..2d2cafd 100644
--- a/src/share/classes/sun/security/x509/URIName.java
+++ b/src/share/classes/sun/security/x509/URIName.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -35,15 +35,15 @@
  * This class implements the URIName as required by the GeneralNames
  * ASN.1 object.
  * <p>
- * [RFC3280] When the subjectAltName extension contains a URI, the name MUST be
+ * [RFC5280] When the subjectAltName extension contains a URI, the name MUST be
  * stored in the uniformResourceIdentifier (an IA5String). The name MUST
  * be a non-relative URL, and MUST follow the URL syntax and encoding
- * rules specified in [RFC 1738].  The name must include both a scheme
+ * rules specified in [RFC 3986].  The name must include both a scheme
  * (e.g., "http" or "ftp") and a scheme-specific-part.  The scheme-
  * specific-part must include a fully qualified domain name or IP
  * address as the host.
  * <p>
- * As specified in [RFC 1738], the scheme name is not case-sensitive
+ * As specified in [RFC 3986], the scheme name is not case-sensitive
  * (e.g., "http" is equivalent to "HTTP").  The host part is also not
  * case-sensitive, but other components of the scheme-specific-part may
  * be case-sensitive. When comparing URIs, conforming implementations
@@ -113,7 +113,7 @@
         }
 
         host = uri.getHost();
-        // RFC 3280 says that the host should be non-null, but we allow it to
+        // RFC 5280 says that the host should be non-null, but we allow it to
         // be null because some widely deployed certificates contain CDP
         // extensions with URIs that have no hostname (see bugs 4802236 and
         // 5107944).
@@ -148,7 +148,7 @@
     /**
      * Create the URIName object with the specified name constraint. URI
      * name constraints syntax is different than SubjectAltNames, etc. See
-     * 4.2.1.11 of RFC 3280.
+     * 4.2.1.10 of RFC 5280.
      *
      * @param value the URI name constraint
      * @throws IOException if name is not a proper URI name constraint
@@ -300,7 +300,7 @@
      * These results are used in checking NameConstraints during
      * certification path verification.
      * <p>
-     * RFC3280: For URIs, the constraint applies to the host part of the name.
+     * RFC5280: For URIs, the constraint applies to the host part of the name.
      * The constraint may specify a host or a domain.  Examples would be
      * "foo.bar.com";  and ".xyz.com".  When the the constraint begins with
      * a period, it may be expanded with one or more subdomains.  That is,
diff --git a/src/share/classes/sun/security/x509/X500Name.java b/src/share/classes/sun/security/x509/X500Name.java
index 447395c..f70c00f 100644
--- a/src/share/classes/sun/security/x509/X500Name.java
+++ b/src/share/classes/sun/security/x509/X500Name.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -604,7 +604,7 @@
      * Returns a string form of the X.500 distinguished name.
      * The format of the string is from RFC 1779. The returned string
      * may contain non-standardised keywords for more readability
-     * (keywords from RFCs 1779, 2253, and 3280).
+     * (keywords from RFCs 1779, 2253, and 5280).
      */
     public String toString() {
         if (dn == null) {
@@ -865,7 +865,7 @@
      *     O="Sue, Grabbit and Runn" or
      *     O=Sue\, Grabbit and Runn
      *
-     * This method can parse RFC 1779, 2253 or 4514 DNs and non-standard 3280
+     * This method can parse RFC 1779, 2253 or 4514 DNs and non-standard 5280
      * keywords. Additional keywords can be specified in the keyword/OID map.
      */
     private void parseDN(String input, Map<String, String> keywordMap)
@@ -1104,20 +1104,8 @@
     /****************************************************************/
 
     /*
-     * Maybe return a preallocated OID, to reduce storage costs
-     * and speed recognition of common X.500 attributes.
-     */
-    static ObjectIdentifier intern(ObjectIdentifier oid) {
-        ObjectIdentifier interned = internedOIDs.putIfAbsent(oid, oid);
-        return (interned == null) ? oid : interned;
-    }
-
-    private static final Map<ObjectIdentifier,ObjectIdentifier> internedOIDs
-                        = new HashMap<ObjectIdentifier,ObjectIdentifier>();
-
-    /*
      * Selected OIDs from X.520
-     * Includes all those specified in RFC 3280 as MUST or SHOULD
+     * Includes all those specified in RFC 5280 as MUST or SHOULD
      * be recognized
      */
     private static final int commonName_data[] = { 2, 5, 4, 3 };
@@ -1142,92 +1130,82 @@
         { 0, 9, 2342, 19200300, 100, 1, 1 };
 
 
-    public static final ObjectIdentifier commonName_oid;
-    public static final ObjectIdentifier countryName_oid;
-    public static final ObjectIdentifier localityName_oid;
-    public static final ObjectIdentifier orgName_oid;
-    public static final ObjectIdentifier orgUnitName_oid;
-    public static final ObjectIdentifier stateName_oid;
-    public static final ObjectIdentifier streetAddress_oid;
-    public static final ObjectIdentifier title_oid;
-    public static final ObjectIdentifier DNQUALIFIER_OID;
-    public static final ObjectIdentifier SURNAME_OID;
-    public static final ObjectIdentifier GIVENNAME_OID;
-    public static final ObjectIdentifier INITIALS_OID;
-    public static final ObjectIdentifier GENERATIONQUALIFIER_OID;
-    public static final ObjectIdentifier ipAddress_oid;
-    public static final ObjectIdentifier DOMAIN_COMPONENT_OID;
-    public static final ObjectIdentifier userid_oid;
-    public static final ObjectIdentifier SERIALNUMBER_OID;
+    // OID for the "CN=" attribute, denoting a person's common name.
+    public static final ObjectIdentifier commonName_oid =
+            ObjectIdentifier.newInternal(commonName_data);
 
-    static {
-    /** OID for the "CN=" attribute, denoting a person's common name. */
-        commonName_oid = intern(ObjectIdentifier.newInternal(commonName_data));
+    // OID for the "SERIALNUMBER=" attribute, denoting a serial number for.
+    // a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the
+    // certificate serial number.
+    public static final ObjectIdentifier SERIALNUMBER_OID =
+            ObjectIdentifier.newInternal(SERIALNUMBER_DATA);
 
-    /** OID for the "SERIALNUMBER=" attribute, denoting a serial number for.
-        a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the
-        certificate serial number. */
-        SERIALNUMBER_OID = intern(ObjectIdentifier.newInternal(SERIALNUMBER_DATA));
+    // OID for the "C=" attribute, denoting a country.
+    public static final ObjectIdentifier countryName_oid =
+            ObjectIdentifier.newInternal(countryName_data);
 
-    /** OID for the "C=" attribute, denoting a country. */
-        countryName_oid = intern(ObjectIdentifier.newInternal(countryName_data));
+    // OID for the "L=" attribute, denoting a locality (such as a city).
+    public static final ObjectIdentifier localityName_oid =
+            ObjectIdentifier.newInternal(localityName_data);
 
-    /** OID for the "L=" attribute, denoting a locality (such as a city) */
-        localityName_oid = intern(ObjectIdentifier.newInternal(localityName_data));
+    // OID for the "O=" attribute, denoting an organization name.
+    public static final ObjectIdentifier orgName_oid =
+            ObjectIdentifier.newInternal(orgName_data);
 
-    /** OID for the "O=" attribute, denoting an organization name */
-        orgName_oid = intern(ObjectIdentifier.newInternal(orgName_data));
+    // OID for the "OU=" attribute, denoting an organizational unit name.
+    public static final ObjectIdentifier orgUnitName_oid =
+            ObjectIdentifier.newInternal(orgUnitName_data);
 
-    /** OID for the "OU=" attribute, denoting an organizational unit name */
-        orgUnitName_oid = intern(ObjectIdentifier.newInternal(orgUnitName_data));
+    // OID for the "S=" attribute, denoting a state (such as Delaware).
+    public static final ObjectIdentifier stateName_oid =
+            ObjectIdentifier.newInternal(stateName_data);
 
-    /** OID for the "S=" attribute, denoting a state (such as Delaware) */
-        stateName_oid = intern(ObjectIdentifier.newInternal(stateName_data));
+    // OID for the "STREET=" attribute, denoting a street address.
+    public static final ObjectIdentifier streetAddress_oid =
+            ObjectIdentifier.newInternal(streetAddress_data);
 
-    /** OID for the "STREET=" attribute, denoting a street address. */
-        streetAddress_oid = intern(ObjectIdentifier.newInternal(streetAddress_data));
+    // OID for the "T=" attribute, denoting a person's title.
+    public static final ObjectIdentifier title_oid =
+            ObjectIdentifier.newInternal(title_data);
 
-    /** OID for the "T=" attribute, denoting a person's title. */
-        title_oid = intern(ObjectIdentifier.newInternal(title_data));
+    // OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN
+    // disambiguating information.
+    public static final ObjectIdentifier DNQUALIFIER_OID =
+            ObjectIdentifier.newInternal(DNQUALIFIER_DATA);
 
-    /** OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN
-        disambiguating information.*/
-        DNQUALIFIER_OID = intern(ObjectIdentifier.newInternal(DNQUALIFIER_DATA));
+    // OID for the "SURNAME=" attribute, denoting a person's surname.
+    public static final ObjectIdentifier SURNAME_OID =
+            ObjectIdentifier.newInternal(SURNAME_DATA);
 
-    /** OID for the "SURNAME=" attribute, denoting a person's surname.*/
-        SURNAME_OID = intern(ObjectIdentifier.newInternal(SURNAME_DATA));
+    // OID for the "GIVENNAME=" attribute, denoting a person's given name.
+    public static final ObjectIdentifier GIVENNAME_OID =
+            ObjectIdentifier.newInternal(GIVENNAME_DATA);
 
-    /** OID for the "GIVENNAME=" attribute, denoting a person's given name.*/
-        GIVENNAME_OID = intern(ObjectIdentifier.newInternal(GIVENNAME_DATA));
+    // OID for the "INITIALS=" attribute, denoting a person's initials.
+    public static final ObjectIdentifier INITIALS_OID =
+            ObjectIdentifier.newInternal(INITIALS_DATA);
 
-    /** OID for the "INITIALS=" attribute, denoting a person's initials.*/
-        INITIALS_OID = intern(ObjectIdentifier.newInternal(INITIALS_DATA));
+    // OID for the "GENERATION=" attribute, denoting Jr., II, etc.
+    public static final ObjectIdentifier GENERATIONQUALIFIER_OID =
+            ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA);
 
-    /** OID for the "GENERATION=" attribute, denoting Jr., II, etc.*/
-        GENERATIONQUALIFIER_OID =
-            intern(ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA));
+    // OIDs from other sources which show up in X.500 names we
+    // expect to deal with often.
+    //
+    // OID for "IP=" IP address attributes, used with SKIP.
+    public static final ObjectIdentifier ipAddress_oid =
+            ObjectIdentifier.newInternal(ipAddress_data);
 
-    /*
-     * OIDs from other sources which show up in X.500 names we
-     * expect to deal with often
-     */
-    /** OID for "IP=" IP address attributes, used with SKIP. */
-        ipAddress_oid = intern(ObjectIdentifier.newInternal(ipAddress_data));
+    // Domain component OID from RFC 1274, RFC 2247, RFC 5280.
+    //
+    // OID for "DC=" domain component attributes, used with DNSNames in DN
+    // format.
+    public static final ObjectIdentifier DOMAIN_COMPONENT_OID =
+            ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA);
 
-    /*
-     * Domain component OID from RFC 1274, RFC 2247, RFC 3280
-     */
-
-    /*
-     * OID for "DC=" domain component attributes, used with DNSNames in DN
-     * format
-     */
-        DOMAIN_COMPONENT_OID =
-            intern(ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA));
-
-    /** OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798. */
-        userid_oid = intern(ObjectIdentifier.newInternal(userid_data));
-    }
+    // OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798.
+    public static final ObjectIdentifier userid_oid =
+            ObjectIdentifier.newInternal(userid_data);
 
     /**
      * Return constraint type:<ul>
diff --git a/src/share/classes/sun/security/x509/X509CRLImpl.java b/src/share/classes/sun/security/x509/X509CRLImpl.java
index 84403b3..8cb54ff 100644
--- a/src/share/classes/sun/security/x509/X509CRLImpl.java
+++ b/src/share/classes/sun/security/x509/X509CRLImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -63,7 +63,7 @@
  *     signature            BIT STRING  }
  * </pre>
  * More information can be found in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
  * Public Key Infrastructure Certificate and CRL Profile</a>.
  * <p>
  * The ASN.1 definition of <code>tbsCertList</code> is:
diff --git a/src/share/classes/sun/security/x509/X509CertInfo.java b/src/share/classes/sun/security/x509/X509CertInfo.java
index b7f2dd8..fa64e9d 100644
--- a/src/share/classes/sun/security/x509/X509CertInfo.java
+++ b/src/share/classes/sun/security/x509/X509CertInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -708,7 +708,7 @@
     }
 
     /*
-     * Verify if X.509 V3 Certificate is compliant with RFC 3280.
+     * Verify if X.509 V3 Certificate is compliant with RFC 5280.
      */
     private void verifyCert(X500Name subject,
         CertificateExtensions extensions)
diff --git a/src/share/lib/security/cacerts b/src/share/lib/security/cacerts
index 1db6c41..2adbd11 100644
--- a/src/share/lib/security/cacerts
+++ b/src/share/lib/security/cacerts
Binary files differ
diff --git a/src/share/lib/security/java.security-aix b/src/share/lib/security/java.security-aix
index 69cc59f..6e52f0e 100644
--- a/src/share/lib/security/java.security-aix
+++ b/src/share/lib/security/java.security-aix
@@ -341,7 +341,7 @@
 # By default, the location of the OCSP responder is determined implicitly
 # from the certificate being validated. This property explicitly specifies
 # the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
 # from the certificate or when it requires overriding.
 #
 # Example,
@@ -420,6 +420,32 @@
 #   krb5.kdc.bad.policy = tryLess:2,2000
 krb5.kdc.bad.policy = tryLast
 
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
 # Algorithm restrictions for certification path (CertPath) processing
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -860,8 +886,8 @@
 # Patterns are separated by ";" (semicolon).
 # Whitespace is significant and is considered part of the pattern.
 #
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
 #
 # If a pattern includes a "=", it sets a limit.
 # If a limit appears more than once the last value is used.
diff --git a/src/share/lib/security/java.security-linux b/src/share/lib/security/java.security-linux
index ae28ce7..349c6c9 100644
--- a/src/share/lib/security/java.security-linux
+++ b/src/share/lib/security/java.security-linux
@@ -341,7 +341,7 @@
 # By default, the location of the OCSP responder is determined implicitly
 # from the certificate being validated. This property explicitly specifies
 # the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
 # from the certificate or when it requires overriding.
 #
 # Example,
@@ -420,6 +420,32 @@
 #   krb5.kdc.bad.policy = tryLess:2,2000
 krb5.kdc.bad.policy = tryLast
 
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
 # Algorithm restrictions for certification path (CertPath) processing
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -861,8 +887,8 @@
 # Patterns are separated by ";" (semicolon).
 # Whitespace is significant and is considered part of the pattern.
 #
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
 #
 # If a pattern includes a "=", it sets a limit.
 # If a limit appears more than once the last value is used.
diff --git a/src/share/lib/security/java.security-macosx b/src/share/lib/security/java.security-macosx
index 8af804b..6404a38 100644
--- a/src/share/lib/security/java.security-macosx
+++ b/src/share/lib/security/java.security-macosx
@@ -344,7 +344,7 @@
 # By default, the location of the OCSP responder is determined implicitly
 # from the certificate being validated. This property explicitly specifies
 # the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
 # from the certificate or when it requires overriding.
 #
 # Example,
@@ -423,6 +423,32 @@
 #   krb5.kdc.bad.policy = tryLess:2,2000
 krb5.kdc.bad.policy = tryLast
 
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
 # Algorithm restrictions for certification path (CertPath) processing
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -864,8 +890,8 @@
 # Patterns are separated by ";" (semicolon).
 # Whitespace is significant and is considered part of the pattern.
 #
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
 #
 # If a pattern includes a "=", it sets a limit.
 # If a limit appears more than once the last value is used.
diff --git a/src/share/lib/security/java.security-solaris b/src/share/lib/security/java.security-solaris
index 204871b..25c4785 100644
--- a/src/share/lib/security/java.security-solaris
+++ b/src/share/lib/security/java.security-solaris
@@ -343,7 +343,7 @@
 # By default, the location of the OCSP responder is determined implicitly
 # from the certificate being validated. This property explicitly specifies
 # the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
 # from the certificate or when it requires overriding.
 #
 # Example,
@@ -422,6 +422,32 @@
 #   krb5.kdc.bad.policy = tryLess:2,2000
 krb5.kdc.bad.policy = tryLast
 
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
 # Algorithm restrictions for certification path (CertPath) processing
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -863,8 +889,8 @@
 # Patterns are separated by ";" (semicolon).
 # Whitespace is significant and is considered part of the pattern.
 #
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
 #
 # If a pattern includes a "=", it sets a limit.
 # If a limit appears more than once the last value is used.
diff --git a/src/share/lib/security/java.security-windows b/src/share/lib/security/java.security-windows
index e49d188..36122cc 100644
--- a/src/share/lib/security/java.security-windows
+++ b/src/share/lib/security/java.security-windows
@@ -344,7 +344,7 @@
 # By default, the location of the OCSP responder is determined implicitly
 # from the certificate being validated. This property explicitly specifies
 # the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
 # from the certificate or when it requires overriding.
 #
 # Example,
@@ -423,6 +423,32 @@
 #   krb5.kdc.bad.policy = tryLess:2,2000
 krb5.kdc.bad.policy = tryLast
 
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
 # Algorithm restrictions for certification path (CertPath) processing
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -864,8 +890,8 @@
 # Patterns are separated by ";" (semicolon).
 # Whitespace is significant and is considered part of the pattern.
 #
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
 #
 # If a pattern includes a "=", it sets a limit.
 # If a limit appears more than once the last value is used.
diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c
index 4a45aaa..5485604 100644
--- a/src/share/native/sun/font/freetypeScaler.c
+++ b/src/share/native/sun/font/freetypeScaler.c
@@ -48,6 +48,7 @@
 #include FT_SIZES_H
 #include FT_OUTLINE_H
 #include FT_SYNTHESIS_H
+#include FT_LCD_FILTER_H
 #include FT_MODULE_H
 #include FT_LCD_FILTER_H
 
@@ -941,6 +942,8 @@
             if (logFC) fprintf(stderr, "\n");
 #endif
         }
+
+        FT_Library_SetLcdFilter(scalerInfo->library, FT_LCD_FILTER_DEFAULT);
     }
 
     return 0;
@@ -970,7 +973,7 @@
         jlong pScalerContext, jlong pScaler) {
 
     jobject metrics;
-    jfloat ax, ay, dx, dy, bx, by, lx, ly, mx, my, txx, txy, tyx, tyy;
+    jfloat ax, ay, dx, dy, bx, by, lx, ly, mx, my;
     jfloat f0 = 0.0;
     FTScalerContext *context =
         (FTScalerContext*) jlong_to_ptr(pScalerContext);
@@ -1010,6 +1013,14 @@
     /* See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=657854 */
 #define FT_MulFixFloatShift6(a, b) (((float) (a)) * ((float) (b)) / 65536.0 / 64.0)
 
+#define contextAwareMetricsX(x, y) \
+    (FTFixedToFloat(context->transform.xx) * (x) - \
+     FTFixedToFloat(context->transform.xy) * (y))
+
+#define contextAwareMetricsY(x, y) \
+    (-FTFixedToFloat(context->transform.yx) * (x) + \
+     FTFixedToFloat(context->transform.yy) * (y))
+
     /*
      * See FreeType source code: src/base/ftobjs.c ft_recompute_scaled_metrics()
      * http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1659
@@ -1041,24 +1052,14 @@
                              scalerInfo->face->size->metrics.y_scale));
     my = 0;
 
-    // apply transformation matrix
-    txx = (jfloat)  FTFixedToFloat(context->transform.xx);
-    txy = (jfloat) -FTFixedToFloat(context->transform.xy);
-    tyx = (jfloat) -FTFixedToFloat(context->transform.yx);
-    tyy = (jfloat)  FTFixedToFloat(context->transform.yy);
-    ax = txy * ay;
-    ay = tyy * ay;
-    dx = txy * dy;
-    dy = tyy * dy;
-    lx = txy * ly;
-    ly = tyy * ly;
-    my = tyx * mx;
-    mx = txx * mx; 
-    
     metrics = (*env)->NewObject(env,
-                                sunFontIDs.strikeMetricsClass,
-                                sunFontIDs.strikeMetricsCtr,
-                                ax, ay, dx, dy, bx, by, lx, ly, mx, my);
+        sunFontIDs.strikeMetricsClass,
+        sunFontIDs.strikeMetricsCtr,
+        contextAwareMetricsX(ax, ay), contextAwareMetricsY(ax, ay),
+        contextAwareMetricsX(dx, dy), contextAwareMetricsY(dx, dy),
+        bx, by,
+        contextAwareMetricsX(lx, ly), contextAwareMetricsY(lx, ly),
+        contextAwareMetricsX(mx, my), contextAwareMetricsY(mx, my));
 
     return metrics;
 }
@@ -1125,10 +1126,14 @@
                                  pScalerContext, pScaler, glyphCode);
      info = (GlyphInfo*) jlong_to_ptr(image);
 
-     (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX);
-     (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY);
-
-     free(info);
+     if (info != NULL) {
+         (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX);
+         (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY);
+         free(info);
+     } else {
+         (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, 0.0f);
+         (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, 0.0f);
+     }
 }
 
 
@@ -1680,86 +1685,60 @@
         return 1;
 }
 
+static void addSeg(GPData *gp, jbyte type) {
+    gp->pointTypes[gp->numTypes++] = type;
+}
+
+static void addCoords(GPData *gp, FT_Vector *p) {
+    gp->pointCoords[gp->numCoords++] =  F26Dot6ToFloat(p->x);
+    gp->pointCoords[gp->numCoords++] = -F26Dot6ToFloat(p->y);
+}
+
+static int moveTo(FT_Vector *to, GPData *gp) {
+    if (gp->numCoords)
+        addSeg(gp, SEG_CLOSE);
+    addCoords(gp, to);
+    addSeg(gp, SEG_MOVETO);
+    return FT_Err_Ok;
+}
+
+static int lineTo(FT_Vector *to, GPData *gp) {
+    addCoords(gp, to);
+    addSeg(gp, SEG_LINETO);
+    return FT_Err_Ok;
+}
+
+static int conicTo(FT_Vector *control, FT_Vector *to, GPData *gp) {
+    addCoords(gp, control);
+    addCoords(gp, to);
+    addSeg(gp, SEG_QUADTO);
+    return FT_Err_Ok;
+}
+
+static int cubicTo(FT_Vector *control1,
+                   FT_Vector *control2,
+                   FT_Vector *to,
+                   GPData    *gp) {
+    addCoords(gp, control1);
+    addCoords(gp, control2);
+    addCoords(gp, to);
+    addSeg(gp, SEG_CUBICTO);
+    return FT_Err_Ok;
+}
+
 static void addToGP(GPData* gpdata, FT_Outline*outline) {
-    jbyte current_type=SEG_UNKNOWN;
-    int i, j;
-    jfloat x, y;
+    static const FT_Outline_Funcs outline_funcs = {
+        (FT_Outline_MoveToFunc) moveTo,
+        (FT_Outline_LineToFunc) lineTo,
+        (FT_Outline_ConicToFunc) conicTo,
+        (FT_Outline_CubicToFunc) cubicTo,
+        0, /* shift */
+        0, /* delta */
+    };
 
-    j = 0;
-    for(i=0; i<outline->n_points; i++) {
-        x =  F26Dot6ToFloat(outline->points[i].x);
-        y = -F26Dot6ToFloat(outline->points[i].y);
-
-        if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_ON) {
-            /* If bit 0 is unset, the point is "off" the curve,
-             i.e., a Bezier control point, while it is "on" when set. */
-            if (current_type == SEG_UNKNOWN) { /* special case:
-                                                  very first point */
-                /* add segment */
-                gpdata->pointTypes[gpdata->numTypes++] = SEG_MOVETO;
-                current_type = SEG_LINETO;
-            } else {
-                gpdata->pointTypes[gpdata->numTypes++] = current_type;
-                current_type = SEG_LINETO;
-            }
-        } else {
-            if (current_type == SEG_UNKNOWN) { /* special case:
-                                                   very first point */
-                if (FT_CURVE_TAG(outline->tags[i+1]) == FT_CURVE_TAG_ON) {
-                    /* just skip first point. Adhoc heuristic? */
-                    continue;
-                } else {
-                    x = (x + F26Dot6ToFloat(outline->points[i+1].x))/2;
-                    y = (y - F26Dot6ToFloat(outline->points[i+1].y))/2;
-                    gpdata->pointTypes[gpdata->numTypes++] = SEG_MOVETO;
-                    current_type = SEG_LINETO;
-                }
-            } else if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_CUBIC) {
-                /* Bit 1 is meaningful for 'off' points only.
-                   If set, it indicates a third-order Bezier arc control
-                   point; and a second-order control point if unset.  */
-                current_type = SEG_CUBICTO;
-            } else {
-                /* two successive conic "off" points forces the rasterizer
-                   to create (during the scan-line conversion process
-                   exclusively) a virtual "on" point amidst them, at their
-                   exact middle. This greatly facilitates the definition of
-                   successive conic Bezier arcs.  Moreover, it is the way
-                   outlines are described in the TrueType specification. */
-                if (current_type == SEG_QUADTO) {
-                    gpdata->pointCoords[gpdata->numCoords++] =
-                        F26Dot6ToFloat(outline->points[i].x +
-                        outline->points[i-1].x)/2;
-                    gpdata->pointCoords[gpdata->numCoords++] =
-                        - F26Dot6ToFloat(outline->points[i].y +
-                        outline->points[i-1].y)/2;
-                    gpdata->pointTypes[gpdata->numTypes++] = SEG_QUADTO;
-                }
-                current_type = SEG_QUADTO;
-            }
-        }
-        gpdata->pointCoords[gpdata->numCoords++] = x;
-        gpdata->pointCoords[gpdata->numCoords++] = y;
-        if (outline->contours[j] == i) { //end of contour
-            int start = j > 0 ? outline->contours[j-1]+1 : 0;
-            gpdata->pointTypes[gpdata->numTypes++] = current_type;
-            if (current_type == SEG_QUADTO &&
-            FT_CURVE_TAG(outline->tags[start]) != FT_CURVE_TAG_ON) {
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            (F26Dot6ToFloat(outline->points[start].x) + x)/2;
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            (-F26Dot6ToFloat(outline->points[start].y) + y)/2;
-            } else {
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            F26Dot6ToFloat(outline->points[start].x);
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            -F26Dot6ToFloat(outline->points[start].y);
-            }
-            gpdata->pointTypes[gpdata->numTypes++] = SEG_CLOSE;
-            current_type = SEG_UNKNOWN;
-            j++;
-        }
-    }
+    FT_Outline_Decompose(outline, &outline_funcs, gpdata);
+    if (gpdata->numCoords)
+        addSeg(gpdata, SEG_CLOSE);
 
     /* If set to 1, the outline will be filled using the even-odd fill rule */
     if (outline->flags & FT_OUTLINE_EVEN_ODD_FILL) {
diff --git a/src/share/native/sun/font/layout/MorphTables2.cpp b/src/share/native/sun/font/layout/MorphTables2.cpp
index ff69cb9..eb628a1 100644
--- a/src/share/native/sun/font/layout/MorphTables2.cpp
+++ b/src/share/native/sun/font/layout/MorphTables2.cpp
@@ -192,7 +192,7 @@
         for (subtable = 0;  LE_SUCCESS(success) && subtable < nSubtables; subtable++) {
             if(subtable>0)  {
               le_uint32 length = SWAPL(subtableHeader->length);
-              if (length & 0x03) { // incorrect alignment for 32 bit tables
+              if (length & 0x01) { // incorrect alignment for 32 bit tables
                   success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any
                   return;
               }
diff --git a/src/share/native/sun/java2d/opengl/OGLSurfaceData.c b/src/share/native/sun/java2d/opengl/OGLSurfaceData.c
index 83c0b59..8bff4a8 100644
--- a/src/share/native/sun/java2d/opengl/OGLSurfaceData.c
+++ b/src/share/native/sun/java2d/opengl/OGLSurfaceData.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -37,7 +37,6 @@
  * The following methods are implemented in the windowing system (i.e. GLX
  * and WGL) source files.
  */
-extern jlong OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo);
 extern jboolean OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo);
 extern void OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo);
 
@@ -593,11 +592,14 @@
 OGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
 {
     OGLSDOps *oglsdo = (OGLSDOps *)ops;
-    jlong pConfigInfo = OGLSD_GetNativeConfigInfo(oglsdo);
+    jobject graphicsConfig = oglsdo->graphicsConfig;
 
     JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData",
-                               "dispose", "(JJ)V",
-                               ptr_to_jlong(ops), pConfigInfo);
+                               "dispose",
+                               "(JLsun/java2d/opengl/OGLGraphicsConfig;)V",
+                               ptr_to_jlong(ops), graphicsConfig);
+    (*env)->DeleteGlobalRef(env, graphicsConfig);
+    oglsdo->graphicsConfig = NULL;
 }
 
 /**
diff --git a/src/share/native/sun/java2d/opengl/OGLSurfaceData.h b/src/share/native/sun/java2d/opengl/OGLSurfaceData.h
index 0fc8b3b..62c48ee 100644
--- a/src/share/native/sun/java2d/opengl/OGLSurfaceData.h
+++ b/src/share/native/sun/java2d/opengl/OGLSurfaceData.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -85,6 +85,9 @@
  * Pointer to native-specific (GLX, WGL, etc.) SurfaceData info, such as the
  * native Drawable handle and GraphicsConfig data.
  *
+ *     jobject graphicsConfig;;
+ * Strong reference to the OGLGraphicsConfig used by this OGLSurfaceData.
+ *
  *     jint drawableType;
  * The surface type; can be any one of the surface type constants defined
  * below (OGLSD_WINDOW, OGLSD_TEXTURE, etc).
@@ -162,6 +165,7 @@
 struct _OGLSDOps {
     SurfaceDataOps               sdOps;
     void                         *privOps;
+    jobject                      graphicsConfig;
     jint                         drawableType;
     GLenum                       activeBuffer;
     jboolean                     isOpaque;
diff --git a/src/share/native/sun/security/krb5/nativeccache.c b/src/share/native/sun/security/krb5/nativeccache.c
index 1b50a2e..5ab3f73 100644
--- a/src/share/native/sun/security/krb5/nativeccache.c
+++ b/src/share/native/sun/security/krb5/nativeccache.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -418,7 +418,7 @@
 
                     if (krbcredsConstructor == 0) {
                         krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>",
-                                                                  "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
+                                                                  "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
                         if (krbcredsConstructor == 0) {
                             printf("Couldn't find sun.security.krb5.internal.Ticket constructor\n");
                             break;
@@ -432,7 +432,9 @@
                                                  krbcredsConstructor,
                                                  ticket,
                                                  clientPrincipal,
+                                                 NULL,
                                                  targetPrincipal,
+                                                 NULL,
                                                  encryptionKey,
                                                  ticketFlags,
                                                  authTime,
diff --git a/src/solaris/classes/java/lang/UNIXProcess.java b/src/solaris/classes/java/lang/UNIXProcess.java
index 1793a8f..fe26fd8 100644
--- a/src/solaris/classes/java/lang/UNIXProcess.java
+++ b/src/solaris/classes/java/lang/UNIXProcess.java
@@ -408,8 +408,7 @@
         long deadline = System.nanoTime() + remainingNanos;
 
         do {
-            // Round up to next millisecond
-            wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
+            TimeUnit.NANOSECONDS.timedWait(this, remainingNanos);
             if (hasExited) {
                 return true;
             }
diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java
index d6c3ab7..370224b 100644
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -2421,14 +2421,16 @@
                  //System.out.println("XkbNewKeyboard:"+(xke.get_new_kbd()));
                  break;
             case XConstants.XkbMapNotify :
-                 //TODO: provide a simple unit test.
-                 XlibWrapper.XkbGetUpdatedMap(getDisplay(),
-                                              XConstants.XkbKeyTypesMask    |
-                                              XConstants.XkbKeySymsMask     |
-                                              XConstants.XkbModifierMapMask |
-                                              XConstants.XkbVirtualModsMask,
-                                              awt_XKBDescPtr);
-                 //System.out.println("XkbMap:"+(xke.get_map()));
+                 if (awt_XKBDescPtr != 0) {
+                    //TODO: provide a simple unit test.
+                    XlibWrapper.XkbGetUpdatedMap(getDisplay(),
+                                                 XConstants.XkbKeyTypesMask    |
+                                                 XConstants.XkbKeySymsMask     |
+                                                 XConstants.XkbModifierMapMask |
+                                                 XConstants.XkbVirtualModsMask,
+                                                 awt_XKBDescPtr);
+                 }
+                //System.out.println("XkbMap:"+(xke.get_map()));
                  break;
             case XConstants.XkbStateNotify :
                  // May use it later e.g. to obtain an effective group etc.
diff --git a/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java b/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java
index 50e12e0..bec9c76 100644
--- a/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java
+++ b/src/solaris/classes/sun/java2d/opengl/GLXSurfaceData.java
@@ -41,7 +41,8 @@
     protected X11ComponentPeer peer;
     private GLXGraphicsConfig graphicsConfig;
 
-    private native void initOps(X11ComponentPeer peer, long aData);
+    private native void initOps(OGLGraphicsConfig gc, X11ComponentPeer peer,
+                                long aData);
     protected native boolean initPbuffer(long pData, long pConfigInfo,
                                          boolean isOpaque,
                                          int width, int height);
@@ -52,7 +53,7 @@
         super(gc, cm, type);
         this.peer = peer;
         this.graphicsConfig = gc;
-        initOps(peer, graphicsConfig.getAData());
+        initOps(gc, peer, graphicsConfig.getAData());
     }
 
     public GraphicsConfiguration getDeviceConfiguration() {
diff --git a/src/solaris/native/java/util/TimeZone_md.c b/src/solaris/native/java/util/TimeZone_md.c
index 3507c1c..7ec893b 100644
--- a/src/solaris/native/java/util/TimeZone_md.c
+++ b/src/solaris/native/java/util/TimeZone_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, 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
@@ -42,6 +42,8 @@
 #include "jvm.h"
 #include "TimeZone_md.h"
 
+static char *isFileIdentical(char* buf, size_t size, char *pathname);
+
 #define SKIP_SPACE(p)   while (*p == ' ' || *p == '\t') p++;
 
 #if defined(_ALLBSD_SOURCE)
@@ -65,6 +67,8 @@
 static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
 #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
 
+static const char popularZones[][4] = {"UTC", "GMT"};
+
 #if defined(_AIX)
 static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
 #endif
@@ -114,14 +118,28 @@
 findZoneinfoFile(char *buf, size_t size, const char *dir)
 {
     DIR *dirp = NULL;
-    struct stat statbuf;
     struct dirent64 *dp = NULL;
     struct dirent64 *entry = NULL;
     char *pathname = NULL;
-    int fd = -1;
-    char *dbuf = NULL;
     char *tz = NULL;
 
+    if (strcmp(dir, ZONEINFO_DIR) == 0) {
+        /* fast path for 1st iteration */
+        unsigned int i;
+        for (i = 0; i < sizeof (popularZones) / sizeof (popularZones[0]); i++) {
+            pathname = getPathName(dir, popularZones[i]);
+            if (pathname == NULL) {
+                continue;
+            }
+            tz = isFileIdentical(buf, size, pathname);
+            free((void *) pathname);
+            pathname = NULL;
+            if (tz != NULL) {
+                return tz;
+            }
+        }
+    }
+
     dirp = opendir(dir);
     if (dirp == NULL) {
         return NULL;
@@ -161,40 +179,14 @@
         if (pathname == NULL) {
             break;
         }
-        if (stat(pathname, &statbuf) == -1) {
-            break;
-        }
 
-        if (S_ISDIR(statbuf.st_mode)) {
-            tz = findZoneinfoFile(buf, size, pathname);
-            if (tz != NULL) {
-                break;
-            }
-        } else if (S_ISREG(statbuf.st_mode) && (size_t)statbuf.st_size == size) {
-            dbuf = (char *) malloc(size);
-            if (dbuf == NULL) {
-                break;
-            }
-            if ((fd = open(pathname, O_RDONLY)) == -1) {
-                break;
-            }
-            if (read(fd, dbuf, size) != (ssize_t) size) {
-                break;
-            }
-            if (memcmp(buf, dbuf, size) == 0) {
-                tz = getZoneName(pathname);
-                if (tz != NULL) {
-                    tz = strdup(tz);
-                }
-                break;
-            }
-            free((void *) dbuf);
-            dbuf = NULL;
-            (void) close(fd);
-            fd = -1;
-        }
+        tz = isFileIdentical(buf, size, pathname);
+
         free((void *) pathname);
         pathname = NULL;
+        if (tz != NULL) {
+            break;
+        }
     }
 
     if (entry != NULL) {
@@ -203,16 +195,53 @@
     if (dirp != NULL) {
         (void) closedir(dirp);
     }
-    if (pathname != NULL) {
-        free((void *) pathname);
+    return tz;
+}
+
+/*
+ * Checks if the file pointed to by pathname matches
+ * the data contents in buf.
+ * Returns a representation of the timezone file name
+ * if file match is found, otherwise NULL.
+ */
+static char *
+isFileIdentical(char *buf, size_t size, char *pathname)
+{
+    char *possibleMatch = NULL;
+    struct stat statbuf;
+    char *dbuf = NULL;
+    int fd = -1;
+    int res;
+
+    if (stat(pathname, &statbuf) == -1) {
+        return NULL;
     }
-    if (fd != -1) {
+
+    if (S_ISDIR(statbuf.st_mode)) {
+        possibleMatch  = findZoneinfoFile(buf, size, pathname);
+    } else if (S_ISREG(statbuf.st_mode) && (size_t)statbuf.st_size == size) {
+        dbuf = (char *) malloc(size);
+        if (dbuf == NULL) {
+            return NULL;
+        }
+        if ((fd = open(pathname, O_RDONLY)) == -1) {
+            goto freedata;
+        }
+        if (read(fd, dbuf, size) != (ssize_t) size) {
+            goto freedata;
+        }
+        if (memcmp(buf, dbuf, size) == 0) {
+            possibleMatch = getZoneName(pathname);
+            if (possibleMatch != NULL) {
+                possibleMatch = strdup(possibleMatch);
+            }
+        }
+        freedata:
+        free((void *) dbuf);
+        dbuf = NULL;
         (void) close(fd);
     }
-    if (dbuf != NULL) {
-        free((void *) dbuf);
-    }
-    return tz;
+    return possibleMatch;
 }
 
 #if defined(__linux__) || defined(MACOSX)
diff --git a/src/solaris/native/sun/awt/gtk_interface.c b/src/solaris/native/sun/awt/gtk_interface.c
index 8157efe..42db9b6 100644
--- a/src/solaris/native/sun/awt/gtk_interface.c
+++ b/src/solaris/native/sun/awt/gtk_interface.c
@@ -45,18 +45,18 @@
 
 static GtkLib gtk_libs[] = {
     {
-        GTK_2,
-        JNI_LIB_NAME("gtk-x11-2.0"),
-        VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"),
-        &gtk2_load,
-        &gtk2_check
-    },
-    {
         GTK_3,
         JNI_LIB_NAME("gtk-3"),
         VERSIONED_JNI_LIB_NAME("gtk-3", "0"),
         &gtk3_load,
         &gtk3_check
+    },
+    {
+        GTK_2,
+        JNI_LIB_NAME("gtk-x11-2.0"),
+        VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"),
+        &gtk2_load,
+        &gtk2_check
     }
 };
 
diff --git a/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c b/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
index 1bdd088..ace25e1 100644
--- a/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
+++ b/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -54,23 +54,32 @@
 
 JNIEXPORT void JNICALL
 Java_sun_java2d_opengl_GLXSurfaceData_initOps(JNIEnv *env, jobject glxsd,
+                                              jobject gc,
                                               jobject peer, jlong aData)
 {
 #ifndef HEADLESS
-    GLXSDOps *glxsdo = (GLXSDOps *)malloc(sizeof(GLXSDOps));
-
-    if (glxsdo == NULL) {
-        JNU_ThrowOutOfMemoryError(env, "creating native GLX ops");
+    gc = (*env)->NewGlobalRef(env, gc);
+    if (gc == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
         return;
     }
 
     OGLSDOps *oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, glxsd,
                                                        sizeof(OGLSDOps));
     if (oglsdo == NULL) {
-        free(glxsdo);
+        (*env)->DeleteGlobalRef(env, gc);
         JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
         return;
     }
+    // later the graphicsConfig will be used for deallocation of oglsdo
+    oglsdo->graphicsConfig = gc;
+
+    GLXSDOps *glxsdo = (GLXSDOps *)malloc(sizeof(GLXSDOps));
+
+    if (glxsdo == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "creating native GLX ops");
+        return;
+    }
 
     J2dTraceLn(J2D_TRACE_INFO, "GLXSurfaceData_initOps");
 
@@ -165,39 +174,6 @@
 }
 
 /**
- * Returns a pointer (as a jlong) to the native GLXGraphicsConfigInfo
- * associated with the given OGLSDOps.  This method can be called from
- * shared code to retrieve the native GraphicsConfig data in a platform-
- * independent manner.
- */
-jlong
-OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
-{
-    GLXSDOps *glxsdo;
-
-    if (oglsdo == NULL) {
-        J2dRlsTraceLn(J2D_TRACE_ERROR,
-                      "OGLSD_GetNativeConfigInfo: ops are null");
-        return 0L;
-    }
-
-    glxsdo = (GLXSDOps *)oglsdo->privOps;
-    if (glxsdo == NULL) {
-        J2dRlsTraceLn(J2D_TRACE_ERROR,
-                      "OGLSD_GetNativeConfigInfo: glx ops are null");
-        return 0L;
-    }
-
-    if (glxsdo->configData == NULL) {
-        J2dRlsTraceLn(J2D_TRACE_ERROR,
-                      "OGLSD_GetNativeConfigInfo: config data is null");
-        return 0L;
-    }
-
-    return ptr_to_jlong(glxsdo->configData->glxInfo);
-}
-
-/**
  * Makes the given GraphicsConfig's context current to its associated
  * "scratch" surface.  If there is a problem making the context current,
  * this method will return NULL; otherwise, returns a pointer to the
diff --git a/src/solaris/native/sun/java2d/x11/X11SurfaceData.c b/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
index b4518af..7d1c058 100644
--- a/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+++ b/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
@@ -78,6 +78,7 @@
 static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,
                                SurfaceDataBounds *bounds,
                                jint lockFlags);
+static int X11SD_GetBitmapPad(int pixelStride);
 
 extern jfieldID validID;
 
@@ -438,11 +439,33 @@
         xsdo->drawable = drawable;
         xsdo->isPixmap = JNI_FALSE;
     } else {
+        jboolean sizeIsInvalid = JNI_FALSE;
+        jlong scan = 0;
+
         /*
          * width , height must be nonzero otherwise XCreatePixmap
          * generates BadValue in error_handler
          */
         if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {
+            sizeIsInvalid = JNI_TRUE;
+        } else {
+            XImage* tmpImg = NULL;
+
+            AWT_LOCK();
+            tmpImg = XCreateImage(awt_display,
+                xsdo->configData->awt_visInfo.visual,
+                depth, ZPixmap, 0, NULL, width, height,
+                X11SD_GetBitmapPad(xsdo->configData->pixelStride), 0);
+            if (tmpImg) {
+                scan = (jlong) tmpImg->bytes_per_line;
+                XDestroyImage(tmpImg);
+                tmpImg = NULL;
+            }
+            AWT_UNLOCK();
+            JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+        }
+
+        if (sizeIsInvalid || (scan * height > 0x7FFFFFFFL)) {
             JNU_ThrowOutOfMemoryError(env,
                                   "Can't create offscreen surface");
             return JNI_FALSE;
@@ -457,7 +480,7 @@
         xsdo->pmHeight = height;
 
 #ifdef MITSHM
-        xsdo->shmPMData.pmSize = width * height * depth;
+        xsdo->shmPMData.pmSize = (jlong) width * height * depth;
         xsdo->shmPMData.pixelsReadThreshold = width * height / 8;
         if (forceSharedPixmaps) {
             AWT_LOCK();
@@ -560,7 +583,7 @@
         return NULL;
     }
     shminfo->shmid =
-        shmget(IPC_PRIVATE, height * img->bytes_per_line,
+        shmget(IPC_PRIVATE, (size_t) height * img->bytes_per_line,
                IPC_CREAT|mitShmPermissionMask);
     if (shminfo->shmid < 0) {
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
@@ -622,7 +645,7 @@
         XSync(awt_display, False);
         retImage = cachedXImage;
         cachedXImage = (XImage *)NULL;
-    } else if (width * height * xsdo->depth > 0x10000) {
+    } else if ((jlong) width * height * xsdo->depth > 0x10000) {
         retImage = X11SD_CreateSharedImage(xsdo, width, height);
     }
     return retImage;
@@ -978,7 +1001,7 @@
             int scan = xpriv->img->bytes_per_line;
             xpriv->x = x;
             xpriv->y = y;
-            pRasInfo->rasBase = xpriv->img->data - x * mult - y * scan;
+            pRasInfo->rasBase = xpriv->img->data - x * mult - (intptr_t) y * scan;
             pRasInfo->pixelStride = mult;
             pRasInfo->pixelBitOffset = 0;
             pRasInfo->scanStride = scan;
@@ -1140,8 +1163,8 @@
 
 static void
 X11SD_SwapBytes(X11SDOps *xsdo, XImage * img, int depth, int bpp) {
-    int lengthInBytes = img->height * img->bytes_per_line;
-    int i;
+    jlong lengthInBytes = (jlong) img->height * img->bytes_per_line;
+    jlong i;
 
     switch (depth) {
     case 12:
@@ -1214,7 +1237,7 @@
     Drawable drawable;
     int depth = xsdo->depth;
     int mult = xsdo->configData->pixelStride;
-    int pad = (mult == 3) ? 32 : mult * 8; // pad must be 8, 16, or 32
+    int pad = X11SD_GetBitmapPad(mult);
     jboolean readBits = lockFlags & SD_LOCK_NEED_PIXELS;
 
     x = bounds->x1;
@@ -1280,7 +1303,7 @@
             }
 
             scan = img->bytes_per_line;
-            img->data = malloc(h * scan);
+            img->data = malloc((size_t) h * scan);
             if (img->data == NULL) {
                 XFree(img);
                 return NULL;
@@ -1315,7 +1338,7 @@
                     int i;
 
                     img_addr = img->data +
-                        (temp.y1 - y) * scan + (temp.x1 - x) * mult;
+                        (intptr_t) (temp.y1 - y) * scan + (temp.x1 - x) * mult;
                     temp_scan = temp_image->bytes_per_line;
                     temp_addr = temp_image->data;
                     bytes_to_copy = (temp.x2 - temp.x1) * mult;
@@ -1349,7 +1372,7 @@
                 return NULL;
             }
 
-            img->data = malloc(h * img->bytes_per_line);
+            img->data = malloc((size_t) h * img->bytes_per_line);
             if (img->data == NULL) {
                 XFree(img);
                 return NULL;
@@ -1532,6 +1555,11 @@
 #endif /* MITSHM */
 }
 
+static int X11SD_GetBitmapPad(int pixelStride) {
+    // pad must be 8, 16, or 32
+    return (pixelStride == 3) ? 32 : pixelStride * 8;
+}
+
 #endif /* !HEADLESS */
 
 /*
diff --git a/src/solaris/native/sun/java2d/x11/X11SurfaceData.h b/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
index 91ad462..cc8ae6a 100644
--- a/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
+++ b/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
@@ -81,7 +81,7 @@
     XShmSegmentInfo     *shmSegInfo;    /* Shared Memory Segment Info */
     jint                bytesPerLine;   /* needed for ShMem lock */
     jboolean            xRequestSent;   /* true if x request is sent w/o XSync */
-    jint                pmSize;
+    jlong               pmSize;
 
     jboolean            usingShmPixmap;
     Drawable            pixmap;
diff --git a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
index 4b0c834..9e78793 100644
--- a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
+++ b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
@@ -102,7 +102,7 @@
 
         // determine which version of the JDK is running
         String version = getJavaVersionProperty();
-        debugString("JDK version = "+version);
+        debugString("[INFO]:JDK version = "+version);
         runningOnJDK1_4 = (version.compareTo("1.4") >= 0);
         runningOnJDK1_5 = (version.compareTo("1.5") >= 0);
 
@@ -129,7 +129,7 @@
             Thread abthread = new Thread(new dllRunner());
             abthread.setDaemon(true);
             abthread.start();
-            debugString("AccessBridge started");
+            debugString("[INFO]:AccessBridge started");
         }
     }
 
@@ -148,7 +148,7 @@
     private class shutdownHook implements Runnable {
 
         public void run() {
-            debugString("***** shutdownHook: shutting down...");
+            debugString("[INFO]:***** shutdownHook: shutting down...");
             javaShutdown();
         }
     }
@@ -280,7 +280,7 @@
         try {
             componentParemter[0] = Class.forName("java.awt.Component");
         } catch (ClassNotFoundException e) {
-            debugString("Exception: " + e.toString());
+            debugString("[ERROR]:Exception: " + e.toString());
         }
         Object[] args = new Object[1];
         Component c;
@@ -303,15 +303,15 @@
                         c = (Component) javaGetComponentFromNativeWindowHandleMethod.invoke(toolkit, args);
                         returnVal = true;
                     } catch (InvocationTargetException e) {
-                        debugString("Exception: " + e.toString());
+                        debugString("[ERROR]:Exception: " + e.toString());
                     } catch (IllegalAccessException e) {
-                        debugString("Exception: " + e.toString());
+                        debugString("[ERROR]:Exception: " + e.toString());
                     }
                 }
             } catch (NoSuchMethodException e) {
-                debugString("Exception: " + e.toString());
+                debugString("[ERROR]:Exception: " + e.toString());
             } catch (SecurityException e) {
-                debugString("Exception: " + e.toString());
+                debugString("[ERROR]:Exception: " + e.toString());
             }
 
             // verify getComponentFromNativeWindowHandle() method
@@ -326,17 +326,17 @@
                         Integer i = (Integer) javaGetNativeWindowHandleFromComponentMethod.invoke(toolkit, args);
                         returnVal = true;
                     } catch (InvocationTargetException e) {
-                        debugString("Exception: " + e.toString());
+                        debugString("[ERROR]:Exception: " + e.toString());
                     } catch (IllegalAccessException e) {
-                        debugString("Exception: " + e.toString());
+                        debugString("[ERROR]:Exception: " + e.toString());
                     } catch (Exception e) {
-                        debugString("Exception: " + e.toString());
+                        debugString("[ERROR]:Exception: " + e.toString());
                     }
                 }
             } catch (NoSuchMethodException e) {
-                debugString("Exception: " + e.toString());
+                debugString("[ERROR]:Exception: " + e.toString());
             } catch (SecurityException e) {
-                debugString("Exception: " + e.toString());
+                debugString("[ERROR]:Exception: " + e.toString());
             }
         }
         return returnVal;
@@ -425,12 +425,12 @@
      */
     private void saveContextToWindowHandleMapping(AccessibleContext ac,
                                                   int nativeHandle) {
-        debugString("saveContextToWindowHandleMapping...");
+        debugString("[INFO]:saveContextToWindowHandleMapping...");
         if (ac == null) {
             return;
         }
         if (! contextToWindowHandleMap.containsKey(ac)) {
-            debugString("saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle);
+            debugString("[INFO]: saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle);
             contextToWindowHandleMap.put(ac, nativeHandle);
         }
     }
@@ -473,7 +473,7 @@
      *     returns 0 on error
      */
     private int getNativeWindowHandleFromContext(AccessibleContext ac) {
-    debugString("getNativeWindowHandleFromContext: ac = "+ac);
+    debugString("[INFO]: getNativeWindowHandleFromContext: ac = "+ac);
         try {
             return contextToWindowHandleMap.get(ac);
         } catch (Exception ex) {
@@ -506,10 +506,10 @@
         */
         private Component getComponentFromNativeWindowHandle(int nativeHandle) {
             if (useJAWT_DLL) {
-                debugString("*** calling jawtGetComponentFromNativeWindowHandle");
+                debugString("[INFO]:*** calling jawtGetComponentFromNativeWindowHandle");
                 return jawtGetComponentFromNativeWindowHandle(nativeHandle);
             } else {
-                debugString("*** calling javaGetComponentFromNativeWindowHandle");
+                debugString("[INFO]:*** calling javaGetComponentFromNativeWindowHandle");
                 Object[] args = new Object[1];
                 if (javaGetComponentFromNativeWindowHandleMethod != null) {
                     try {
@@ -527,7 +527,7 @@
                         }
                         return (Component)o;
                     } catch (InvocationTargetException | IllegalAccessException e) {
-                        debugString("Exception: " + e.toString());
+                        debugString("[ERROR]:Exception: " + e.toString());
                     }
                 }
             }
@@ -540,11 +540,11 @@
      */
     private int getNativeWindowHandleFromComponent(final Component target) {
         if (useJAWT_DLL) {
-            debugString("*** calling jawtGetNativeWindowHandleFromComponent");
+            debugString("[INFO]:*** calling jawtGetNativeWindowHandleFromComponent");
             return jawtGetNativeWindowHandleFromComponent(target);
         } else {
             Object[] args = new Object[1];
-            debugString("*** calling javaGetNativeWindowHandleFromComponent");
+            debugString("[INFO]:*** calling javaGetNativeWindowHandleFromComponent");
             if (javaGetNativeWindowHandleFromComponentMethod != null) {
                 try {
                     args[0] = target;
@@ -559,9 +559,9 @@
                     contextToWindowHandleMap.put(ac, i);
                     return i.intValue();
                 } catch (InvocationTargetException e) {
-                    debugString("Exception: " + e.toString());
+                    debugString("[ERROR]:Exception: " + e.toString());
                 } catch (IllegalAccessException e) {
-                    debugString("Exception: " + e.toString());
+                    debugString("[ERROR]:Exception: " + e.toString());
                 }
             }
         }
@@ -620,8 +620,8 @@
      */
     private AccessibleContext getAccessibleContextAt_1(final int x, final int y,
                                                       final AccessibleContext parent) {
-        debugString(" : getAccessibleContextAt_1 called");
-        debugString("   -> x = " + x + " y = " + y + " parent = " + parent);
+        debugString("[INFO]: getAccessibleContextAt_1 called");
+        debugString("[INFO]:   -> x = " + x + " y = " + y + " parent = " + parent);
 
         if (parent == null) return null;
             final AccessibleComponent acmp = InvocationUtils.invokeAndWait(new Callable<AccessibleComponent>() {
@@ -668,8 +668,8 @@
      */
     private AccessibleContext getAccessibleContextAt_2(final int x, final int y,
                                                       AccessibleContext parent) {
-        debugString("getAccessibleContextAt_2 called");
-        debugString("   -> x = " + x + " y = " + y + " parent = " + parent);
+        debugString("[INFO]: getAccessibleContextAt_2 called");
+        debugString("[INFO]:   -> x = " + x + " y = " + y + " parent = " + parent);
 
         return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
             @Override
@@ -678,7 +678,7 @@
                 if (a != null) {
                     AccessibleContext childAC = a.getAccessibleContext();
                     if (childAC != null) {
-                        debugString("   returning childAC = " + childAC);
+                        debugString("[INFO]:   returning childAC = " + childAC);
                         return childAC;
                     }
                 }
@@ -713,7 +713,7 @@
      * returns the AccessibleName from an AccessibleContext
      */
     private String getAccessibleNameFromContext(final AccessibleContext ac) {
-        debugString("***** ac = "+ac.getClass());
+        debugString("[INFO]: ***** ac = "+ac.getClass());
         if (ac != null) {
             String s = InvocationUtils.invokeAndWait(new Callable<String>() {
                 @Override
@@ -723,13 +723,13 @@
             }, ac);
             if (s != null) {
                 references.increment(s);
-                debugString("Returning AccessibleName from Context: " + s);
+                debugString("[INFO]: Returning AccessibleName from Context: " + s);
                 return s;
             } else {
                 return null;
             }
         } else {
-            debugString("getAccessibleNameFromContext; ac = null!");
+            debugString("[INFO]: getAccessibleNameFromContext; ac = null!");
             return null;
         }
     }
@@ -754,7 +754,7 @@
                 }
             }, ac);
             if ( ( null != nameString ) && ( 0 != nameString.length () ) ) {
-                debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName.");
+                debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName.");
                 references.increment (nameString);
                 return nameString;
             }
@@ -765,12 +765,12 @@
                 }
             }, ac);
             if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) {
-                debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription.");
+                debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription.");
                 references.increment (descriptionString);
                 return descriptionString;
             }
 
-            debugString ("The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName");
+            debugString ("[WARN]: The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName");
             /*
             Step 2:
             =======
@@ -807,7 +807,7 @@
             }
 
             if (false == bExtendedSearch) {
-                debugString ("bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm.  role = " + ( role != null ? role.toDisplayString(Locale.US) : "null") );
+                debugString ("[INFO]: bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm.  role = " + ( role != null ? role.toDisplayString(Locale.US) : "null") );
                 /*
                 Step 3:
                 =======
@@ -840,7 +840,7 @@
                         }, ac);
                         String text = getAccessibleTextRangeFromContext (ac, 0, charCount);
                         if (null != text) {
-                            debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object.");
+                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object.");
                             references.increment (text);
                             return text;
                         }
@@ -848,7 +848,7 @@
                     /*
                     Does the label support the Accessible Icon Interface?
                     */
-                    debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
+                    debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
                     final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                         @Override
                         public AccessibleIcon[] call() throws Exception {
@@ -863,7 +863,7 @@
                             }
                         }, ac);
                         if (iconDescription != null){
-                            debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object.");
+                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object.");
                             references.increment (iconDescription);
                             return iconDescription;
                         }
@@ -885,7 +885,7 @@
                                     }
                                 }, ac);
                                 final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent);
-                                debugString ("bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell.");
+                                debugString ("[INFO]: bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell.");
                                 if (acTableCell != null) {
                                     final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                                         @Override
@@ -900,7 +900,7 @@
                                             }
                                         }, ac);
                                         if (iconDescription != null){
-                                            debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object.");
+                                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object.");
                                             references.increment (iconDescription);
                                             return iconDescription;
                                         }
@@ -914,7 +914,7 @@
                     /*
                     Does the button support the Accessible Icon Interface?
                     */
-                    debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
+                    debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
                     final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon []>() {
                         public AccessibleIcon [] call() {
                             return ac.getAccessibleIcon ();
@@ -927,7 +927,7 @@
                             }
                         }, ac);
                         if (iconDescription != null){
-                            debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object.");
+                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object.");
                             references.increment (iconDescription);
                             return iconDescription;
                         }
@@ -1007,7 +1007,7 @@
             if ( (AccessibleRole.SLIDER == role) &&
                  (AccessibleRole.PANEL == parentRole) &&
                  (null != parentName) ) {
-                debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object.");
+                debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object.");
                 references.increment (parentName);
                 return parentName;
             }
@@ -1024,11 +1024,11 @@
                  (AccessibleRole.COMBO_BOX == parentRole) ) {
                 bIsEditCombo = true;
                 if (null != parentName) {
-                    debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object.");
+                    debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object.");
                     references.increment (parentName);
                     return parentName;
                 } else if (null != parentDescription) {
-                    debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object.");
+                    debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object.");
                     references.increment (parentDescription);
                     return parentDescription;
                 }
@@ -1072,11 +1072,11 @@
                                 String labelName = labelContext.getAccessibleName ();
                                 String labelDescription = labelContext.getAccessibleDescription ();
                                 if (null != labelName) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case.");
                                     references.increment (labelName);
                                     return labelName;
                                 } else if (null != labelDescription) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case.");
                                     references.increment (labelDescription);
                                     return labelDescription;
                                 }
@@ -1085,7 +1085,7 @@
                     }
                 }
             } else {
-                debugString ("bk -- This version of Java does not support AccessibleContext::getAccessibleRelationSet.");
+                debugString ("[ERROR]:bk -- This version of Java does not support AccessibleContext::getAccessibleRelationSet.");
             }
 
             //Note: add AccessibleContext to use InvocationUtils.invokeAndWait
@@ -1172,7 +1172,7 @@
                                     }
                                 }, ac);
                                 if ( null != childName ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
                                     references.increment (childName);
                                     return childName;
                                 }
@@ -1182,7 +1182,7 @@
                                     }
                                 }, ac);
                                 if ( null != childDescription ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
                                     references.increment (childDescription);
                                     return childDescription;
                                 }
@@ -1194,7 +1194,7 @@
                                     }
                                 }, ac);
                                 if ( null != childName ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
                                     references.increment (childName);
                                     return childName;
                                 }
@@ -1204,7 +1204,7 @@
                                     }
                                 }, ac);
                                 if ( null != childDescription ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
                                     references.increment (childDescription);
                                     return childDescription;
                                 }
@@ -1251,7 +1251,7 @@
                                     }
                                 }, ac);
                                 if ( null != childName ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
                                     references.increment (childName);
                                     return childName;
                                 }
@@ -1261,7 +1261,7 @@
                                     }
                                 }, ac);
                                 if ( null != childDescription ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
                                     references.increment (childDescription);
                                     return childDescription;
                                 }
@@ -1273,7 +1273,7 @@
                                     }
                                 }, ac);
                                 if ( null != childName ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
                                     references.increment (childName);
                                     return childName;
                                 }
@@ -1283,7 +1283,7 @@
                                     }
                                 }, ac);
                                 if ( null != childDescription ) {
-                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
+                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
                                     references.increment (childDescription);
                                     return childDescription;
                                 }
@@ -1344,7 +1344,7 @@
                                         }
                                     }, ac);
                                     if ( null != childName ) {
-                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                         references.increment (childName);
                                         return childName;
                                     }
@@ -1354,7 +1354,7 @@
                                         }
                                     }, ac);
                                     if ( null != childDescription ) {
-                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                         references.increment (childDescription);
                                         return childDescription;
                                     }
@@ -1402,7 +1402,7 @@
                                         }
                                     }, ac);
                                     if ( null != childName ) {
-                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                         references.increment (childName);
                                         return childName;
                                     }
@@ -1412,7 +1412,7 @@
                                         }
                                     }, ac);
                                     if ( null != childDescription ) {
-                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                         references.increment (childDescription);
                                         return childDescription;
                                     }
@@ -1425,7 +1425,7 @@
             }
             return null;
         } else {
-            debugString ("AccessBridge::getVirtualAccessibleNameFromContext error - ac == null.");
+            debugString ("[ERROR]: AccessBridge::getVirtualAccessibleNameFromContext error - ac == null.");
             return null;
         }
     }
@@ -1443,11 +1443,11 @@
             }, ac);
             if (s != null) {
                 references.increment(s);
-                debugString("Returning AccessibleDescription from Context: " + s);
+                debugString("[INFO]: Returning AccessibleDescription from Context: " + s);
                 return s;
             }
         } else {
-            debugString("getAccessibleDescriptionFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleDescriptionFromContext; ac = null");
         }
         return null;
     }
@@ -1467,12 +1467,12 @@
                 String s = role.toDisplayString(Locale.US);
                 if (s != null) {
                     references.increment(s);
-                    debugString("Returning AccessibleRole from Context: " + s);
+                    debugString("[INFO]: Returning AccessibleRole from Context: " + s);
                     return s;
                 }
             }
         } else {
-            debugString("getAccessibleRoleStringFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleRoleStringFromContext; ac = null");
         }
         return null;
     }
@@ -1511,12 +1511,12 @@
                         s += AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US);
                     }
                     references.increment(s);
-                    debugString("Returning AccessibleStateSet from Context: " + s);
+                    debugString("[INFO]: Returning AccessibleStateSet from Context: " + s);
                     return s;
                 }
             }
         } else {
-            debugString("getAccessibleStatesStringFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleStatesStringFromContext; ac = null");
         }
         return null;
     }
@@ -1542,11 +1542,11 @@
                     }
                 }
                 references.increment(s);
-                debugString("Returning AccessibleStateSet en_US from Context: " + s);
+                debugString("[INFO]: Returning AccessibleStateSet en_US from Context: " + s);
                 return s;
             }
         }
-        debugString("getAccessibleStatesStringFromContext; ac = null");
+        debugString("[ERROR]: getAccessibleStatesStringFromContext; ac = null");
         return null;
     }
 
@@ -1700,11 +1700,11 @@
         if (ac != null) {
             Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
             if (r != null) {
-                debugString(" - Returning Accessible x coord from Context: " + r.x);
+                debugString("[INFO]: Returning Accessible x coord from Context: " + r.x);
                 return r.x;
             }
         } else {
-            debugString("getAccessibleXcoordFromContext ac = null");
+            debugString("[ERROR]: getAccessibleXcoordFromContext ac = null");
         }
         return -1;
     }
@@ -1713,14 +1713,14 @@
      * returns the AccessibleComponent y-coord from an AccessibleContext
      */
     private int getAccessibleYcoordFromContext(AccessibleContext ac) {
-        debugString("getAccessibleYcoordFromContext() called");
+        debugString("[INFO]: getAccessibleYcoordFromContext() called");
         if (ac != null) {
             Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
             if (r != null) {
                 return r.y;
             }
         } else {
-        debugString("getAccessibleYcoordFromContext; ac = null");
+        debugString("[ERROR]: getAccessibleYcoordFromContext; ac = null");
         }
         return -1;
     }
@@ -1735,7 +1735,7 @@
                 return r.height;
             }
         } else {
-            debugString("getAccessibleHeightFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleHeightFromContext; ac = null");
         }
         return -1;
     }
@@ -1750,7 +1750,7 @@
                 return r.width;
             }
         } else {
-            debugString("getAccessibleWidthFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleWidthFromContext; ac = null");
         }
         return -1;
     }
@@ -1765,11 +1765,11 @@
                     return ac.getAccessibleComponent();
                 }, ac);
             if (acmp != null) {
-                debugString("Returning AccessibleComponent Context");
+                debugString("[INFO]: Returning AccessibleComponent Context");
                 return acmp;
             }
         } else {
-            debugString("getAccessibleComponentFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleComponentFromContext; ac = null");
         }
         return null;
     }
@@ -1778,7 +1778,7 @@
      * returns the AccessibleAction from an AccessibleContext
      */
     private AccessibleAction getAccessibleActionFromContext(final AccessibleContext ac) {
-        debugString("Returning AccessibleAction Context");
+        debugString("[INFO]: Returning AccessibleAction Context");
         return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleAction>() {
             @Override
             public AccessibleAction call() throws Exception {
@@ -1830,7 +1830,7 @@
      * XXX
      */
     private Rectangle getCaretLocation(final AccessibleContext ac) {
-    debugString("getCaretLocation");
+    debugString("[INFO]: getCaretLocation");
         if (ac==null)
             return null;
         return InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
@@ -1951,7 +1951,7 @@
      */
     private int getAccessibleIndexAtPointFromContext(final AccessibleContext ac,
                                                     final int x, final int y) {
-        debugString("getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y);
+        debugString("[INFO]: getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y);
         if (ac==null)
             return -1;
         return InvocationUtils.invokeAndWait(new Callable<Integer>() {
@@ -2005,7 +2005,7 @@
                 return s;
             }
         } else {
-            debugString("getAccessibleLetterAtIndexFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleLetterAtIndexFromContext; ac = null");
         }
         return null;
     }
@@ -2028,7 +2028,7 @@
                 return s;
             }
         } else {
-            debugString("getAccessibleWordAtIndexFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleWordAtIndexFromContext; ac = null");
         }
         return null;
     }
@@ -2051,7 +2051,7 @@
                 return s;
             }
         } else {
-            debugString("getAccessibleSentenceAtIndexFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleSentenceAtIndexFromContext; ac = null");
         }
         return null;
     }
@@ -2109,7 +2109,7 @@
                 return s;
             }
         } else {
-            debugString("getAccessibleTextSelectedTextFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleTextSelectedTextFromContext; ac = null");
         }
         return null;
     }
@@ -2370,7 +2370,7 @@
                 return r.x;
             }
         } else {
-            debugString("getAccessibleXcoordTextRectAtIndexFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleXcoordTextRectAtIndexFromContext; ac = null");
         }
         return -1;
     }
@@ -2385,7 +2385,7 @@
                 return r.y;
             }
         } else {
-            debugString("getAccessibleYcoordTextRectAtIndexFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleYcoordTextRectAtIndexFromContext; ac = null");
         }
         return -1;
     }
@@ -2400,7 +2400,7 @@
                 return r.height;
             }
         } else {
-            debugString("getAccessibleHeightTextRectAtIndexFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleHeightTextRectAtIndexFromContext; ac = null");
         }
         return -1;
     }
@@ -2415,7 +2415,7 @@
                 return r.width;
             }
         } else {
-            debugString("getAccessibleWidthTextRectAtIndexFromContext; ac = null");
+            debugString("[ERROR]: getAccessibleWidthTextRectAtIndexFromContext; ac = null");
         }
         return -1;
     }
@@ -2429,7 +2429,7 @@
         if (as != null) {
             return StyleConstants.isBold(as);
         } else {
-            debugString("getBoldFromAttributeSet; as = null");
+            debugString("[ERROR]: getBoldFromAttributeSet; as = null");
         }
         return false;
     }
@@ -2441,7 +2441,7 @@
         if (as != null) {
             return StyleConstants.isItalic(as);
         } else {
-            debugString("getItalicFromAttributeSet; as = null");
+            debugString("[ERROR]: getItalicFromAttributeSet; as = null");
         }
         return false;
     }
@@ -2453,7 +2453,7 @@
         if (as != null) {
             return StyleConstants.isUnderline(as);
         } else {
-            debugString("getUnderlineFromAttributeSet; as = null");
+            debugString("[ERROR]: getUnderlineFromAttributeSet; as = null");
         }
         return false;
     }
@@ -2465,7 +2465,7 @@
         if (as != null) {
             return StyleConstants.isStrikeThrough(as);
         } else {
-            debugString("getStrikethroughFromAttributeSet; as = null");
+            debugString("[ERROR]: getStrikethroughFromAttributeSet; as = null");
         }
         return false;
     }
@@ -2477,7 +2477,7 @@
         if (as != null) {
             return StyleConstants.isSuperscript(as);
         } else {
-            debugString("getSuperscriptFromAttributeSet; as = null");
+            debugString("[ERROR]: getSuperscriptFromAttributeSet; as = null");
         }
         return false;
     }
@@ -2489,7 +2489,7 @@
         if (as != null) {
             return StyleConstants.isSubscript(as);
         } else {
-            debugString("getSubscriptFromAttributeSet; as = null");
+            debugString("[ERROR]: getSubscriptFromAttributeSet; as = null");
         }
         return false;
     }
@@ -2505,7 +2505,7 @@
                 return s;
             }
         } else {
-            debugString("getBackgroundColorFromAttributeSet; as = null");
+            debugString("[ERROR]: getBackgroundColorFromAttributeSet; as = null");
         }
         return null;
     }
@@ -2521,7 +2521,7 @@
                 return s;
             }
         } else {
-            debugString("getForegroundColorFromAttributeSet; as = null");
+            debugString("[ERROR]: getForegroundColorFromAttributeSet; as = null");
         }
         return null;
     }
@@ -2537,7 +2537,7 @@
                 return s;
             }
         } else {
-            debugString("getFontFamilyFromAttributeSet; as = null");
+            debugString("[ERROR]: getFontFamilyFromAttributeSet; as = null");
         }
         return null;
     }
@@ -2549,7 +2549,7 @@
         if (as != null) {
             return StyleConstants.getFontSize(as);
         } else {
-            debugString("getFontSizeFromAttributeSet; as = null");
+            debugString("[ERROR]: getFontSizeFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2561,7 +2561,7 @@
         if (as != null) {
             return StyleConstants.getAlignment(as);
         } else {
-            debugString("getAlignmentFromAttributeSet; as = null");
+            debugString("[ERROR]: getAlignmentFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2573,7 +2573,7 @@
         if (as != null) {
             return StyleConstants.getBidiLevel(as);
         } else {
-            debugString("getBidiLevelFromAttributeSet; as = null");
+            debugString("[ERROR]: getBidiLevelFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2586,7 +2586,7 @@
         if (as != null) {
             return StyleConstants.getFirstLineIndent(as);
         } else {
-            debugString("getFirstLineIndentFromAttributeSet; as = null");
+            debugString("[ERROR]: getFirstLineIndentFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2598,7 +2598,7 @@
         if (as != null) {
             return StyleConstants.getLeftIndent(as);
         } else {
-            debugString("getLeftIndentFromAttributeSet; as = null");
+            debugString("[ERROR]: getLeftIndentFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2610,7 +2610,7 @@
         if (as != null) {
             return StyleConstants.getRightIndent(as);
         } else {
-            debugString("getRightIndentFromAttributeSet; as = null");
+            debugString("[ERROR]: getRightIndentFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2622,7 +2622,7 @@
         if (as != null) {
             return StyleConstants.getLineSpacing(as);
         } else {
-            debugString("getLineSpacingFromAttributeSet; as = null");
+            debugString("[ERROR]: getLineSpacingFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2634,7 +2634,7 @@
         if (as != null) {
             return StyleConstants.getSpaceAbove(as);
         } else {
-            debugString("getSpaceAboveFromAttributeSet; as = null");
+            debugString("[ERROR]: getSpaceAboveFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2646,7 +2646,7 @@
         if (as != null) {
             return StyleConstants.getSpaceBelow(as);
         } else {
-            debugString("getSpaceBelowFromAttributeSet; as = null");
+            debugString("[ERROR]: getSpaceBelowFromAttributeSet; as = null");
         }
         return -1;
     }
@@ -2795,7 +2795,7 @@
                 }
             }
         } else {
-            debugString("getCurrentAccessibleValueFromContext; ac = null");
+            debugString("[ERROR]: getCurrentAccessibleValueFromContext; ac = null");
         }
         return null;
     }
@@ -2823,7 +2823,7 @@
                 }
             }
         } else {
-            debugString("getMaximumAccessibleValueFromContext; ac = null");
+            debugString("[ERROR]: getMaximumAccessibleValueFromContext; ac = null");
         }
         return null;
     }
@@ -2851,7 +2851,7 @@
                 }
             }
         } else {
-            debugString("getMinimumAccessibleValueFromContext; ac = null");
+            debugString("[ERROR]: getMinimumAccessibleValueFromContext; ac = null");
         }
         return null;
     }
@@ -3038,7 +3038,7 @@
      * returns the row count for an AccessibleTable
      */
     private int getAccessibleTableRowCount(final AccessibleContext ac) {
-        debugString("##### getAccessibleTableRowCount");
+        debugString("[INFO]: ##### getAccessibleTableRowCount");
         return InvocationUtils.invokeAndWait(new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
@@ -3057,7 +3057,7 @@
      * returns the column count for an AccessibleTable
      */
     private int getAccessibleTableColumnCount(final AccessibleContext ac) {
-        debugString("##### getAccessibleTableColumnCount");
+        debugString("[INFO]: ##### getAccessibleTableColumnCount");
         return InvocationUtils.invokeAndWait(new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
@@ -3077,7 +3077,7 @@
      */
     private AccessibleContext getAccessibleTableCellAccessibleContext(final AccessibleTable at,
                                                                       final int row, final int column) {
-        debugString("getAccessibleTableCellAccessibleContext: at = "+at.getClass());
+        debugString("[INFO]: getAccessibleTableCellAccessibleContext: at = "+at.getClass());
         if (at == null) return null;
         return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
             @Override
@@ -3122,7 +3122,7 @@
      * returns the index of a cell at a given row and column in an AccessibleTable
      */
     private int getAccessibleTableCellIndex(final AccessibleTable at, int row, int column) {
-        debugString("##### getAccessibleTableCellIndex: at="+at);
+        debugString("[INFO]: ##### getAccessibleTableCellIndex: at="+at);
         if (at != null) {
             int cellIndex = row *
                 InvocationUtils.invokeAndWait(new Callable<Integer>() {
@@ -3132,10 +3132,10 @@
                     }
                 }, getContextFromAccessibleTable(at)) +
                 column;
-            debugString("   ##### getAccessibleTableCellIndex="+cellIndex);
+            debugString("[INFO]:    ##### getAccessibleTableCellIndex="+cellIndex);
             return cellIndex;
         }
-        debugString(" ##### getAccessibleTableCellIndex FAILED");
+        debugString("[ERROR]: ##### getAccessibleTableCellIndex FAILED");
         return -1;
     }
 
@@ -3143,7 +3143,7 @@
      * returns the row extent of a cell at a given row and column in an AccessibleTable
      */
     private int getAccessibleTableCellRowExtent(final AccessibleTable at, final int row, final int column) {
-        debugString("##### getAccessibleTableCellRowExtent");
+        debugString("[INFO]: ##### getAccessibleTableCellRowExtent");
         if (at != null) {
             int rowExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                                                               @Override
@@ -3152,10 +3152,10 @@
                                                               }
                                                           },
                     getContextFromAccessibleTable(at));
-            debugString("   ##### getAccessibleTableCellRowExtent="+rowExtent);
+            debugString("[INFO]:   ##### getAccessibleTableCellRowExtent="+rowExtent);
             return rowExtent;
         }
-        debugString(" ##### getAccessibleTableCellRowExtent FAILED");
+        debugString("[ERROR]: ##### getAccessibleTableCellRowExtent FAILED");
         return -1;
     }
 
@@ -3163,7 +3163,7 @@
      * returns the column extent of a cell at a given row and column in an AccessibleTable
      */
     private int getAccessibleTableCellColumnExtent(final AccessibleTable at, final int row, final int column) {
-        debugString("##### getAccessibleTableCellColumnExtent");
+        debugString("[INFO]: ##### getAccessibleTableCellColumnExtent");
         if (at != null) {
             int columnExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                                                                  @Override
@@ -3172,10 +3172,10 @@
                                                                  }
                                                              },
                     getContextFromAccessibleTable(at));
-            debugString("   ##### getAccessibleTableCellColumnExtent="+columnExtent);
+            debugString("[INFO]:   ##### getAccessibleTableCellColumnExtent="+columnExtent);
             return columnExtent;
         }
-        debugString(" ##### getAccessibleTableCellColumnExtent FAILED");
+        debugString("[ERROR]: ##### getAccessibleTableCellColumnExtent FAILED");
         return -1;
     }
 
@@ -3184,7 +3184,7 @@
      */
     private boolean isAccessibleTableCellSelected(final AccessibleTable at, final int row,
                          final int column) {
-        debugString("##### isAccessibleTableCellSelected: ["+row+"]["+column+"]");
+        debugString("[INFO]: ##### isAccessibleTableCellSelected: ["+row+"]["+column+"]");
         if (at == null)
             return false;
         return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
@@ -3211,7 +3211,7 @@
      * AccessibleTable
      */
     private AccessibleTable getAccessibleTableRowHeader(final AccessibleContext ac) {
-        debugString(" #####  getAccessibleTableRowHeader called");
+        debugString("[INFO]: #####  getAccessibleTableRowHeader called");
         AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
             @Override
             public AccessibleTable call() throws Exception {
@@ -3235,7 +3235,7 @@
      * AccessibleTable
      */
     private AccessibleTable getAccessibleTableColumnHeader(final AccessibleContext ac) {
-    debugString("##### getAccessibleTableColumnHeader");
+    debugString("[INFO]: ##### getAccessibleTableColumnHeader");
         if (ac == null)
             return null;
         AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
@@ -3274,7 +3274,7 @@
      */
     private int getAccessibleTableRowHeaderRowCount(AccessibleContext ac) {
 
-    debugString(" #####  getAccessibleTableRowHeaderRowCount called");
+    debugString("[INFO]: #####  getAccessibleTableRowHeaderRowCount called");
         if (ac != null) {
             final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
             if (atRowHeader != null) {
@@ -3297,7 +3297,7 @@
      * the row header in an AccessibleTable
      */
     private int getAccessibleTableRowHeaderColumnCount(AccessibleContext ac) {
-        debugString(" #####  getAccessibleTableRowHeaderColumnCount called");
+        debugString("[INFO]: #####  getAccessibleTableRowHeaderColumnCount called");
         if (ac != null) {
             final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
             if (atRowHeader != null) {
@@ -3312,7 +3312,7 @@
                 }, ac);
             }
         }
-        debugString(" ##### getAccessibleTableRowHeaderColumnCount FAILED");
+        debugString("[ERROR]: ##### getAccessibleTableRowHeaderColumnCount FAILED");
         return -1;
     }
 
@@ -3322,7 +3322,7 @@
      */
     private int getAccessibleTableColumnHeaderRowCount(AccessibleContext ac) {
 
-    debugString("##### getAccessibleTableColumnHeaderRowCount");
+    debugString("[INFO]: ##### getAccessibleTableColumnHeaderRowCount");
         if (ac != null) {
             final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
             if (atColumnHeader != null) {
@@ -3337,7 +3337,7 @@
                 }, ac);
             }
         }
-        debugString(" ##### getAccessibleTableColumnHeaderRowCount FAILED");
+        debugString("[ERROR]: ##### getAccessibleTableColumnHeaderRowCount FAILED");
         return -1;
     }
 
@@ -3347,7 +3347,7 @@
      */
     private int getAccessibleTableColumnHeaderColumnCount(AccessibleContext ac) {
 
-    debugString("#####  getAccessibleTableColumnHeaderColumnCount");
+    debugString("[ERROR]: #####  getAccessibleTableColumnHeaderColumnCount");
         if (ac != null) {
             final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
             if (atColumnHeader != null) {
@@ -3362,7 +3362,7 @@
                 }, ac);
             }
         }
-        debugString(" ##### getAccessibleTableColumnHeaderColumnCount FAILED");
+        debugString("[ERROR]: ##### getAccessibleTableColumnHeaderColumnCount FAILED");
         return -1;
     }
 
@@ -3630,7 +3630,7 @@
      */
     private AccessibleContext getAccessibleRelationTarget(final AccessibleContext ac,
                                                          final int i, final int j) {
-        debugString("***** getAccessibleRelationTarget");
+        debugString("[INFO]: ***** getAccessibleRelationTarget");
         return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
             @Override
             public AccessibleContext call() throws Exception {
@@ -3663,7 +3663,7 @@
      * Returns the AccessibleHypertext
      */
     private AccessibleHypertext getAccessibleHypertext(final AccessibleContext ac) {
-        debugString("getAccessibleHyperlink");
+        debugString("[INFO]: getAccessibleHyperlink");
         if (ac==null)
             return null;
         AccessibleHypertext hypertext = InvocationUtils.invokeAndWait(new Callable<AccessibleHypertext>() {
@@ -3684,7 +3684,7 @@
      * Returns the number of AccessibleHyperlinks
      */
     private int getAccessibleHyperlinkCount(AccessibleContext ac) {
-        debugString("getAccessibleHyperlinkCount");
+        debugString("[INFO]: getAccessibleHyperlinkCount");
         if (ac == null) {
             return 0;
         }
@@ -3705,7 +3705,7 @@
      * Returns the hyperlink at the specified index
      */
     private AccessibleHyperlink getAccessibleHyperlink(final AccessibleHypertext hypertext, final int i) {
-        debugString("getAccessibleHyperlink");
+        debugString("[INFO]: getAccessibleHyperlink");
         if (hypertext == null) {
             return null;
         }
@@ -3737,7 +3737,7 @@
      * Returns the hyperlink object description
      */
     private String getAccessibleHyperlinkText(final AccessibleHyperlink link) {
-        debugString("getAccessibleHyperlinkText");
+        debugString("[INFO]: getAccessibleHyperlinkText");
         if (link == null) {
             return null;
         }
@@ -3757,7 +3757,7 @@
      * Returns the hyperlink URL
      */
     private String getAccessibleHyperlinkURL(final AccessibleHyperlink link) {
-        debugString("getAccessibleHyperlinkURL");
+        debugString("[INFO]: getAccessibleHyperlinkURL");
         if (link == null) {
             return null;
         }
@@ -3778,7 +3778,7 @@
      * Returns the start index of the hyperlink text
      */
     private int getAccessibleHyperlinkStartIndex(final AccessibleHyperlink link) {
-        debugString("getAccessibleHyperlinkStartIndex");
+        debugString("[INFO]: getAccessibleHyperlinkStartIndex");
         if (link == null) {
             return -1;
         }
@@ -3794,7 +3794,7 @@
      * Returns the end index of the hyperlink text
      */
     private int getAccessibleHyperlinkEndIndex(final AccessibleHyperlink link) {
-        debugString("getAccessibleHyperlinkEndIndex");
+        debugString("[INFO]: getAccessibleHyperlinkEndIndex");
         if (link == null) {
             return -1;
         }
@@ -3812,7 +3812,7 @@
      * is no hyperlink associated with this index.
      */
     private int getAccessibleHypertextLinkIndex(final AccessibleHypertext hypertext, final int charIndex) {
-        debugString("getAccessibleHypertextLinkIndex: charIndex = "+charIndex);
+        debugString("[INFO]: getAccessibleHypertextLinkIndex: charIndex = "+charIndex);
         if (hypertext == null) {
             return -1;
         }
@@ -3822,7 +3822,7 @@
                 return hypertext.getLinkIndex(charIndex);
             }
         }, hyperTextContextMap.get(hypertext));
-        debugString("getAccessibleHypertextLinkIndex returning "+linkIndex);
+        debugString("[INFO]: getAccessibleHypertextLinkIndex returning "+linkIndex);
         return linkIndex;
     }
 
@@ -3841,7 +3841,7 @@
                 return link.doAccessibleAction(0);
             }
         }, ac);
-        debugString("activateAccessibleHyperlink: returning = "+retval);
+        debugString("[INFO]: activateAccessibleHyperlink: returning = "+retval);
         return retval;
     }
 
@@ -3969,17 +3969,17 @@
         int fKey = fKeyNumber(keyStroke);
         if (fKey != 0) {
             // return 0x00000001 through 0x00000018
-            debugString("   Shortcut is: F" + fKey);
+            debugString("[INFO]:   Shortcut is: F" + fKey);
             return (char)fKey;
         }
         // If the accelerator is a control character, return it
         int keyCode = controlCode(keyStroke);
         if (keyCode != 0) {
-            debugString("   Shortcut is control character: " + Integer.toHexString(keyCode));
+            debugString("[INFO]:   Shortcut is control character: " + Integer.toHexString(keyCode));
             return (char)keyCode;
         }
         String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());
-        debugString("   Shortcut is: " + keyText);
+        debugString("[INFO]:   Shortcut is: " + keyText);
         if (keyText != null || keyText.length() > 0) {
             CharSequence seq = keyText.subSequence(0, 1);
             if (seq != null || seq.length() > 0) {
@@ -3995,7 +3995,7 @@
     private int getModifiers(KeyStroke keyStroke) {
         if (keyStroke == null)
             return 0;
-        debugString("In AccessBridge.getModifiers");
+        debugString("[INFO]: In AccessBridge.getModifiers");
         // modifiers is a bit strip where bits 0-7 indicate a traditional modifier
         // such as Ctrl/Alt/Shift, bit 8 indicates an F key shortcut, and bit 9 indicates
         // a control code shortcut such as the delete key.
@@ -4022,23 +4022,23 @@
             // 0-3 are shift, ctrl, meta, alt
             // 4-7 are for Solaris workstations (though not being used)
             if (text.startsWith("met")) {
-                debugString("   found meta");
+                debugString("[INFO]:   found meta");
                 modifiers |= ActionEvent.META_MASK;
             }
             if (text.startsWith("ctr")) {
-                debugString("   found ctrl");
+                debugString("[INFO]:   found ctrl");
                 modifiers |= ActionEvent.CTRL_MASK;
             }
             if (text.startsWith("alt")) {
-                debugString("   found alt");
+                debugString("[INFO]:   found alt");
                 modifiers |= ActionEvent.ALT_MASK;
             }
             if (text.startsWith("shi")) {
-                debugString("   found shift");
+                debugString("[INFO]:   found shift");
                 modifiers |= ActionEvent.SHIFT_MASK;
             }
         }
-        debugString("   returning modifiers: 0x" + Integer.toHexString(modifiers));
+        debugString("[INFO]:   returning modifiers: 0x" + Integer.toHexString(modifiers));
         return modifiers;
     }
 
@@ -4117,7 +4117,7 @@
      * return the number of icons associated with this context
      */
     private int getAccessibleIconsCount(final AccessibleContext ac) {
-        debugString("getAccessibleIconsCount");
+        debugString("[INFO]: getAccessibleIconsCount");
         if (ac == null) {
             return 0;
         }
@@ -4137,7 +4137,7 @@
      * return icon description at the specified index
      */
     private String getAccessibleIconDescription(final AccessibleContext ac, final int index) {
-        debugString("getAccessibleIconDescription: index = "+index);
+        debugString("[INFO]: getAccessibleIconDescription: index = "+index);
         if (ac == null) {
             return null;
         }
@@ -4157,7 +4157,7 @@
      * return icon height at the specified index
      */
     private int getAccessibleIconHeight(final AccessibleContext ac, final int index) {
-        debugString("getAccessibleIconHeight: index = "+index);
+        debugString("[INFO]: getAccessibleIconHeight: index = "+index);
         if (ac == null) {
             return 0;
         }
@@ -4177,7 +4177,7 @@
      * return icon width at the specified index
      */
     private int getAccessibleIconWidth(final AccessibleContext ac, final int index) {
-        debugString("getAccessibleIconWidth: index = "+index);
+        debugString("[INFO]: getAccessibleIconWidth: index = "+index);
         if (ac == null) {
             return 0;
         }
@@ -4199,7 +4199,7 @@
      * return the number of icons associated with this context
      */
     private int getAccessibleActionsCount(final AccessibleContext ac) {
-        debugString("getAccessibleActionsCount");
+        debugString("[INFO]: getAccessibleActionsCount");
         if (ac == null) {
             return 0;
         }
@@ -4218,7 +4218,7 @@
      * return icon description at the specified index
      */
     private String getAccessibleActionName(final AccessibleContext ac, final int index) {
-        debugString("getAccessibleActionName: index = "+index);
+        debugString("[INFO]: getAccessibleActionName: index = "+index);
         if (ac == null) {
             return null;
         }
@@ -4237,7 +4237,7 @@
      * return icon description at the specified index
      */
     private boolean doAccessibleActions(final AccessibleContext ac, final String name) {
-        debugString("doAccessibleActions: action name = "+name);
+        debugString("[INFO]: doAccessibleActions: action name = "+name);
         if (ac == null || name == null) {
             return false;
         }
@@ -4275,14 +4275,14 @@
      * Returns whether successful.
      */
     private boolean setTextContents(final AccessibleContext ac, final String text) {
-        debugString("setTextContents: ac = "+ac+"; text = "+text);
+        debugString("[INFO]: setTextContents: ac = "+ac+"; text = "+text);
 
         if (! (ac instanceof AccessibleEditableText)) {
-            debugString("   ac not instanceof AccessibleEditableText: "+ac);
+            debugString("[WARN]:   ac not instanceof AccessibleEditableText: "+ac);
             return false;
         }
         if (text == null) {
-            debugString("   text is null");
+            debugString("[WARN]:   text is null");
             return false;
         }
 
@@ -4319,7 +4319,7 @@
      * (AccessibleContext)0 on error.
      */
     private AccessibleContext getTopLevelObject (final AccessibleContext ac) {
-        debugString("getTopLevelObject; ac = "+ac);
+        debugString("[INFO]: getTopLevelObject; ac = "+ac);
         if (ac == null) {
             return null;
         }
@@ -4356,8 +4356,7 @@
      */
     private AccessibleContext getParentWithRole (final AccessibleContext ac,
                                                  final String roleName) {
-        debugString("getParentWithRole; ac = "+ac);
-        debugString("role = "+roleName);
+        debugString("[INFO]: getParentWithRole; ac = "+ac + "\n role = "+roleName);
         if (ac == null || roleName == null) {
             return null;
         }
@@ -4413,7 +4412,7 @@
      * Returns -1 on error.
      */
     private int getObjectDepth(final AccessibleContext ac) {
-        debugString("getObjectDepth: ac = "+ac);
+        debugString("[INFO]: getObjectDepth: ac = "+ac);
 
         if (ac == null) {
             return -1;
@@ -4442,7 +4441,7 @@
      * Returns (AccessibleContext)0 on error.
      */
     private AccessibleContext getActiveDescendent (final AccessibleContext ac) {
-        debugString("getActiveDescendent: ac = "+ac);
+        debugString("[INFO]: getActiveDescendent: ac = "+ac);
         if (ac == null) {
             return null;
         }
@@ -4510,7 +4509,7 @@
      * Bug ID 4916682 - Implement JAWS AccessibleName policy
      */
     private String getJAWSAccessibleName(final AccessibleContext ac) {
-        debugString("getJAWSAccessibleName");
+        debugString("[INFO]:  getJAWSAccessibleName");
         if (ac == null) {
             return null;
         }
@@ -4529,7 +4528,7 @@
      * Bug ID 4944757 - requestFocus method needed
      */
     private boolean requestFocus(final AccessibleContext ac) {
-        debugString("requestFocus");
+        debugString("[INFO]:  requestFocus");
         if (ac == null) {
             return false;
         }
@@ -4554,7 +4553,7 @@
      * Bug ID 4944758 - selectTextRange method needed
      */
     private boolean selectTextRange(final AccessibleContext ac, final int startIndex, final int endIndex) {
-        debugString("selectTextRange: start = "+startIndex+"; end = "+endIndex);
+        debugString("[INFO]:  selectTextRange: start = "+startIndex+"; end = "+endIndex);
         if (ac == null) {
             return false;
         }
@@ -4580,7 +4579,7 @@
      * Bug ID 4944770 - setCaretPosition method needed
      */
     private boolean setCaretPosition(final AccessibleContext ac, final int position) {
-        debugString("setCaretPosition: position = "+position);
+        debugString("[INFO]: setCaretPosition: position = "+position);
         if (ac == null) {
             return false;
         }
@@ -4608,13 +4607,13 @@
     private boolean _foundVisibleChild;
 
     private int getVisibleChildrenCount(AccessibleContext ac) {
-        debugString("getVisibleChildrenCount");
+        debugString("[INFO]: getVisibleChildrenCount");
         if (ac == null) {
             return -1;
         }
         _visibleChildrenCount = 0;
         _getVisibleChildrenCount(ac);
-        debugString("  _visibleChildrenCount = "+_visibleChildrenCount);
+        debugString("[INFO]:   _visibleChildrenCount = "+_visibleChildrenCount);
         return _visibleChildrenCount;
     }
 
@@ -4754,7 +4753,7 @@
      * Bug ID 4944762- getVisibleChildren for list-like components needed
      */
     private AccessibleContext getVisibleChild(AccessibleContext ac, int index) {
-        debugString("getVisibleChild: index = "+index);
+        debugString("[INFO]: getVisibleChild: index = "+index);
         if (ac == null) {
             return null;
         }
@@ -4764,7 +4763,7 @@
         _getVisibleChild(ac, index);
 
         if (_visibleChild != null) {
-            debugString( "    getVisibleChild: found child = " +
+            debugString( "[INFO]:     getVisibleChild: found child = " +
                          InvocationUtils.invokeAndWait(new Callable<String>() {
                              @Override
                              public String call() throws Exception {
@@ -4953,7 +4952,7 @@
         */
         void increment(Object o) {
             if (o == null){
-                debugString("ObjectReferences::increment - Passed in object is null");
+                debugString("[WARN]: ObjectReferences::increment - Passed in object is null");
                 return;
             }
 
@@ -4974,10 +4973,10 @@
                 if (aRef.value == 0) {
                     refs.remove(o);
                 } else if (aRef.value < 0) {
-                    debugString("ERROR: decrementing reference count below 0");
+                    debugString("[ERROR]: decrementing reference count below 0");
                 }
             } else {
-                debugString("ERROR: object to decrement not in ObjectReferences table");
+                debugString("[ERROR]: object to decrement not in ObjectReferences table");
             }
         }
 
@@ -5312,7 +5311,7 @@
         // This is invoked on the EDT , as
         public void propertyChange(PropertyChangeEvent e) {
 
-            accessBridge.debugString("propertyChange(" + e.toString() + ") called");
+            accessBridge.debugString("[INFO]: propertyChange(" + e.toString() + ") called");
 
             if (e != null && (accessibilityEventMask & PROPERTY_EVENTS) != 0) {
                 Object o = e.getSource();
@@ -5330,7 +5329,7 @@
                 if (ac != null) {
                     InvocationUtils.registerAccessibleContext(ac, AppContext.getAppContext());
 
-                    accessBridge.debugString("AccessibleContext: " + ac);
+                    accessBridge.debugString("[INFO]: AccessibleContext: " + ac);
                     String propertyName = e.getPropertyName();
 
                     if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) {
@@ -5343,8 +5342,7 @@
                         if (e.getNewValue() instanceof Integer) {
                             newValue = ((Integer) e.getNewValue()).intValue();
                         }
-                        accessBridge.debugString(" - about to call propertyCaretChange()");
-                        accessBridge.debugString("   old value: " + oldValue + "new value: " + newValue);
+                        accessBridge.debugString("[INFO]:  - about to call propertyCaretChange()   old value: " + oldValue + "new value: " + newValue);
                         accessBridge.propertyCaretChange(e, ac, oldValue, newValue);
 
                     } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY) == 0) {
@@ -5357,8 +5355,7 @@
                         if (e.getNewValue() != null) {
                             newValue = e.getNewValue().toString();
                         }
-                        accessBridge.debugString(" - about to call propertyDescriptionChange()");
-                        accessBridge.debugString("   old value: " + oldValue + "new value: " + newValue);
+                        accessBridge.debugString("[INFO]:  - about to call propertyDescriptionChange()   old value: " + oldValue + "new value: " + newValue);
                         accessBridge.propertyDescriptionChange(e, ac, oldValue, newValue);
 
                     } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_NAME_PROPERTY) == 0) {
@@ -5371,12 +5368,11 @@
                         if (e.getNewValue() != null) {
                             newValue = e.getNewValue().toString();
                         }
-                        accessBridge.debugString(" - about to call propertyNameChange()");
-                        accessBridge.debugString("   old value: " + oldValue + " new value: " + newValue);
+                        accessBridge.debugString("[INFO]:  - about to call propertyNameChange()   old value: " + oldValue + " new value: " + newValue);
                         accessBridge.propertyNameChange(e, ac, oldValue, newValue);
 
                     } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) == 0) {
-                        accessBridge.debugString(" - about to call propertySelectionChange() " + ac +  "   " + Thread.currentThread() + "   " + e.getSource());
+                        accessBridge.debugString("[INFO]:  - about to call propertySelectionChange() " + ac +  "   " + Thread.currentThread() + "   " + e.getSource());
 
                         accessBridge.propertySelectionChange(e, ac);
 
@@ -5394,11 +5390,11 @@
                             newValue = newState.toDisplayString(Locale.US);
                         }
 
-                        accessBridge.debugString(" - about to call propertyStateChange()");
+                        accessBridge.debugString("[INFO]:  - about to call propertyStateChange()");
                         accessBridge.propertyStateChange(e, ac, oldValue, newValue);
 
                     } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0) {
-                        accessBridge.debugString(" - about to call propertyTextChange()");
+                        accessBridge.debugString("[INFO]:  - about to call propertyTextChange()");
                         accessBridge.propertyTextChange(e, ac);
 
                     } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY) == 0) {  // strings 'cause of floating point, etc.
@@ -5411,7 +5407,7 @@
                         if (e.getNewValue() != null) {
                             newValue = e.getNewValue().toString();
                         }
-                        accessBridge.debugString(" - about to call propertyDescriptionChange()");
+                        accessBridge.debugString("[INFO]:  - about to call propertyDescriptionChange()");
                         accessBridge.propertyValueChange(e, ac, oldValue, newValue);
 
                     } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY) == 0) {
@@ -5430,8 +5426,7 @@
                             newAC = (AccessibleContext) e.getNewValue();
                             InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
                         }
-                        accessBridge.debugString(" - about to call propertyChildChange()");
-                        accessBridge.debugString("   old AC: " + oldAC + "new AC: " + newAC);
+                        accessBridge.debugString("[INFO]:  - about to call propertyChildChange()   old AC: " + oldAC + "new AC: " + newAC);
                         accessBridge.propertyChildChange(e, ac, oldAC, newAC);
 
                     } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0) {
@@ -5494,10 +5489,7 @@
             }
             prevAC = newAC;
 
-            accessBridge.debugString("  - about to call propertyActiveDescendentChange()");
-            accessBridge.debugString("   AC: " + ac);
-            accessBridge.debugString("   old AC: " + oldAC + "new AC: " + newAC);
-
+            accessBridge.debugString("[INFO]:   - about to call propertyActiveDescendentChange()   AC: " + ac + "   old AC: " + oldAC + "new AC: " + newAC);
             InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext());
             InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
             accessBridge.propertyActiveDescendentChange(e, ac, oldAC, newAC);
@@ -5553,10 +5545,9 @@
                         // This is a popup with an item selected
                         FocusEvent e =
                         new FocusEvent(last, FocusEvent.FOCUS_GAINED);
-                        accessBridge.debugString(" - about to call focusGained()");
                         AccessibleContext focusedAC = last.getAccessibleContext();
                         InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(last));
-                        accessBridge.debugString("   AC: " + focusedAC);
+                        accessBridge.debugString("[INFO]:  - about to call focusGained()   AC: " + focusedAC);
                         accessBridge.focusGained(e, focusedAC);
                     }
                 }
@@ -5565,10 +5556,9 @@
                 if (focusOwner instanceof Accessible) {
                     FocusEvent e = new FocusEvent(focusOwner,
                                                   FocusEvent.FOCUS_GAINED);
-                    accessBridge.debugString(" - about to call focusGained()");
                     AccessibleContext focusedAC = focusOwner.getAccessibleContext();
                     InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(focusOwner));
-                    accessBridge.debugString("   AC: " + focusedAC);
+                    accessBridge.debugString("[INFO]:  - about to call focusGained()   AC: " + focusedAC);
                     accessBridge.focusGained(e, focusedAC);
                 }
             }
@@ -5578,8 +5568,7 @@
             if (e != null && (javaEventMask & FOCUS_LOST_EVENTS) != 0) {
                 Accessible a = Translator.getAccessible(e.getSource());
                 if (a != null) {
-                    accessBridge.debugString(" - about to call focusLost()");
-                    accessBridge.debugString("   AC: " + a.getAccessibleContext());
+                    accessBridge.debugString("[INFO]:  - about to call focusLost()   AC: " + a.getAccessibleContext());
                     AccessibleContext context = a.getAccessibleContext();
                     InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                     accessBridge.focusLost(e, context);
@@ -6282,7 +6271,7 @@
                     isLeaf = treeModel.isLeaf(obj);
                 }
             }
-            debugString("AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap);
+            debugString("[INFO]: AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap);
         }
 
         private TreePath getChildTreePath(int i) {
@@ -6322,14 +6311,14 @@
         }
 
         private Component getCurrentComponent() {
-            debugString("AccessibleJTreeNode: getCurrentComponent");
+            debugString("[INFO]: AccessibleJTreeNode: getCurrentComponent");
             // is the object visible?
             // if so, get row, selected, focus & leaf state,
             // and then get the renderer component and return it
             if (tree != null && tree.isVisible(path)) {
                 TreeCellRenderer r = tree.getCellRenderer();
                 if (r == null) {
-                    debugString("  returning null 1");
+                    debugString("[WARN]:  returning null 1");
                     return null;
                 }
                 TreeUI ui = tree.getUI();
@@ -6341,11 +6330,11 @@
                     Component retval = r.getTreeCellRendererComponent(tree, obj,
                                                                       selected, expanded,
                                                                       isLeaf, row, hasFocus);
-                    debugString("  returning = "+retval.getClass());
+                    debugString("[INFO]:   returning = "+retval.getClass());
                     return retval;
                 }
             }
-            debugString("  returning null 2");
+            debugString("[WARN]:  returning null 2");
             return null;
         }
 
@@ -6358,13 +6347,13 @@
          * object does not have a name
          */
         public String getAccessibleName() {
-            debugString("AccessibleJTreeNode: getAccessibleName");
+            debugString("[INFO]: AccessibleJTreeNode: getAccessibleName");
             AccessibleContext ac = getCurrentAccessibleContext();
             if (ac != null) {
                 String name = ac.getAccessibleName();
                 if ((name != null) && (!name.isEmpty())) {
                     String retval = ac.getAccessibleName();
-                    debugString("    returning "+retval);
+                    debugString("[INFO]:     returning "+retval);
                     return retval;
                 } else {
                     return null;
diff --git a/src/windows/classes/java/lang/ProcessImpl.java b/src/windows/classes/java/lang/ProcessImpl.java
index 37c3237..1970260 100644
--- a/src/windows/classes/java/lang/ProcessImpl.java
+++ b/src/windows/classes/java/lang/ProcessImpl.java
@@ -520,11 +520,15 @@
         if (timeout <= 0) return false;
 
         long remainingNanos  = unit.toNanos(timeout);
-        long deadline = System.nanoTime() + remainingNanos ;
+        long deadline = System.nanoTime() + remainingNanos;
 
         do {
             // Round up to next millisecond
             long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L);
+            if (msTimeout < 0) {
+                // if wraps around then wait a long while
+                msTimeout = Integer.MAX_VALUE;
+            }
             waitForTimeoutInterruptibly(handle, msTimeout);
             if (Thread.interrupted())
                 throw new InterruptedException();
@@ -538,7 +542,7 @@
     }
 
     private static native void waitForTimeoutInterruptibly(
-        long handle, long timeout);
+        long handle, long timeoutMillis);
 
     public void destroy() { terminateProcess(handle); }
 
diff --git a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
index add8f73..bc4039a 100644
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -25,7 +25,8 @@
 
 package sun.awt.shell;
 
-import java.awt.*;
+import java.awt.Image;
+import java.awt.Toolkit;
 import java.awt.image.BufferedImage;
 
 import java.io.File;
@@ -33,14 +34,29 @@
 import java.io.IOException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Stream;
 
-import static sun.awt.shell.Win32ShellFolder2.*;
 import sun.awt.OSInfo;
 import sun.misc.ThreadGroupUtils;
+import sun.util.logging.PlatformLogger;
+
+import static sun.awt.shell.Win32ShellFolder2.DESKTOP;
+import static sun.awt.shell.Win32ShellFolder2.DRIVES;
+import static sun.awt.shell.Win32ShellFolder2.Invoker;
+import static sun.awt.shell.Win32ShellFolder2.NETWORK;
+import static sun.awt.shell.Win32ShellFolder2.PERSONAL;
+import static sun.awt.shell.Win32ShellFolder2.RECENT;
 
 // NOTE: This class supersedes Win32ShellFolderManager, which was removed
 //       from distribution after version 1.4.2.
@@ -54,6 +70,9 @@
 
 public class Win32ShellFolderManager2 extends ShellFolderManager {
 
+    private static final PlatformLogger
+            log = PlatformLogger.getLogger("sun.awt.shell.Win32ShellFolderManager2");
+
     static {
         // Load library here
         sun.awt.windows.WToolkit.loadLibraries();
@@ -137,12 +156,13 @@
         if (desktop == null) {
             try {
                 desktop = new Win32ShellFolder2(DESKTOP);
-            } catch (SecurityException e) {
-                // Ignore error
-            } catch (IOException e) {
-                // Ignore error
-            } catch (InterruptedException e) {
-                // Ignore error
+            } catch (final SecurityException ignored) {
+                // Ignore, the message may have sensitive information, not
+                // accessible other ways
+            } catch (IOException | InterruptedException e) {
+                if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+                    log.warning("Cannot access 'Desktop'", e);
+                }
             }
         }
         return desktop;
@@ -152,12 +172,13 @@
         if (drives == null) {
             try {
                 drives = new Win32ShellFolder2(DRIVES);
-            } catch (SecurityException e) {
-                // Ignore error
-            } catch (IOException e) {
-                // Ignore error
-            } catch (InterruptedException e) {
-                // Ignore error
+            } catch (final SecurityException ignored) {
+                // Ignore, the message may have sensitive information, not
+                // accessible other ways
+            } catch (IOException | InterruptedException e) {
+                if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+                    log.warning("Cannot access 'Drives'", e);
+                }
             }
         }
         return drives;
@@ -170,12 +191,13 @@
                 if (path != null) {
                     recent = createShellFolder(getDesktop(), new File(path));
                 }
-            } catch (SecurityException e) {
-                // Ignore error
-            } catch (InterruptedException e) {
-                // Ignore error
-            } catch (IOException e) {
-                // Ignore error
+            } catch (final SecurityException ignored) {
+                // Ignore, the message may have sensitive information, not
+                // accessible other ways
+            } catch (InterruptedException | IOException e) {
+                if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+                    log.warning("Cannot access 'Recent'", e);
+                }
             }
         }
         return recent;
@@ -185,12 +207,13 @@
         if (network == null) {
             try {
                 network = new Win32ShellFolder2(NETWORK);
-            } catch (SecurityException e) {
-                // Ignore error
-            } catch (IOException e) {
-                // Ignore error
-            } catch (InterruptedException e) {
-                // Ignore error
+            } catch (final SecurityException ignored) {
+                // Ignore, the message may have sensitive information, not
+                // accessible other ways
+            } catch (IOException | InterruptedException e) {
+                if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+                    log.warning("Cannot access 'Network'", e);
+                }
             }
         }
         return network;
@@ -210,12 +233,13 @@
                         personal.setIsPersonal();
                     }
                 }
-            } catch (SecurityException e) {
-                // Ignore error
-            } catch (InterruptedException e) {
-                // Ignore error
-            } catch (IOException e) {
-                // Ignore error
+            } catch (final SecurityException ignored) {
+                // Ignore, the message may have sensitive information, not
+                // accessible other ways
+            } catch (InterruptedException | IOException e) {
+                if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+                    log.warning("Cannot access 'Personal'", e);
+                }
             }
         }
         return personal;
@@ -316,8 +340,14 @@
                         folders.add(createShellFolder(new File((String)value)));
                     }
                 } catch (IOException e) {
+                    if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+                        log.warning("Cannot read value = " + value, e);
+                    }
                     // Skip this value
                 } catch (InterruptedException e) {
+                    if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+                        log.warning("Cannot read value = " + value, e);
+                    }
                     // Return empty result
                     return new File[0];
                 }
diff --git a/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java b/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java
index bc24304..94c54bf 100644
--- a/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java
+++ b/src/windows/classes/sun/java2d/opengl/WGLSurfaceData.java
@@ -45,8 +45,8 @@
     protected double scaleX = 1;
     protected double scaleY = 1;
 
-    private native void initOps(long pConfigInfo, WComponentPeer peer,
-                                long hwnd);
+    private native void initOps(OGLGraphicsConfig gc, long pConfigInfo,
+                                WComponentPeer peer, long hwnd);
     protected native boolean initPbuffer(long pData, long pConfigInfo,
                                          boolean isOpaque,
                                          int width, int height);
@@ -64,7 +64,7 @@
         long pConfigInfo = gc.getNativeConfigInfo();
         long hwnd = peer != null ? peer.getHWnd() : 0L;
 
-        initOps(pConfigInfo, peer, hwnd);
+        initOps(gc, pConfigInfo, peer, hwnd);
     }
 
     @Override
diff --git a/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java b/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
index a436d58..5839a5e 100644
--- a/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
+++ b/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
@@ -36,7 +36,6 @@
 import sun.security.krb5.internal.ccache.*;
 import java.io.IOException;
 import java.util.Arrays;
-import javax.security.auth.kerberos.KerberosPrincipal;
 import sun.security.util.Password;
 import javax.security.auth.kerberos.KeyTab;
 
@@ -53,22 +52,9 @@
 
     /**
      * The main method is used to accept user command line input for ticket
-     * request.
-     * <p>
-     * Usage: kinit [-A] [-f] [-p] [-c cachename] [[-k [-t keytab_file_name]]
-     * [principal] [password]
-     * <ul>
-     * <li>    -A        do not include addresses
-     * <li>    -f        forwardable
-     * <li>    -p        proxiable
-     * <li>    -c        cache name (i.e., FILE://c:\temp\mykrb5cc)
-     * <li>    -k        use keytab
-     * <li>    -t        keytab file name
-     * <li>    principal the principal name (i.e., duke@java.sun.com)
-     * <li>    password  the principal's Kerberos password
-     * </ul>
-     * <p>
-     * Use java sun.security.krb5.tools.Kinit -help to bring up help menu.
+     * request. Read {@link KinitOptions#printHelp} for usages or call
+     *    java sun.security.krb5.internal.tools.Kinit -help
+     * to bring up help menu.
      * <p>
      * We currently support only file-based credentials cache to
      * store the tickets obtained from the KDC.
@@ -146,6 +132,49 @@
         } else {
             options = new KinitOptions(args);
         }
+        switch (options.action) {
+            case 1:
+                acquire();
+                break;
+            case 2:
+                renew();
+                break;
+            default:
+                throw new KrbException("kinit does not support action "
+                        + options.action);
+        }
+    }
+
+    private void renew()
+            throws IOException, RealmException, KrbException {
+
+        PrincipalName principal = options.getPrincipal();
+        String realm = principal.getRealmAsString();
+        CredentialsCache cache = CredentialsCache.getInstance(options.cachename);
+
+        if (cache == null) {
+            throw new IOException("Unable to find existing cache file " +
+                    options.cachename);
+        }
+        sun.security.krb5.internal.ccache.Credentials credentials =
+                cache.getCreds(PrincipalName.tgsService(realm, realm));
+
+        credentials = credentials.setKrbCreds()
+                .renew()
+                .toCCacheCreds();
+
+        cache = CredentialsCache.create(principal, options.cachename);
+        if (cache == null) {
+            throw new IOException("Unable to create the cache file " +
+                    options.cachename);
+        }
+        cache.update(credentials);
+        cache.save();
+    }
+
+    private void acquire()
+            throws IOException, RealmException, KrbException {
+
         String princName = null;
         PrincipalName principal = options.getPrincipal();
         if (principal != null) {
@@ -216,6 +245,9 @@
         if (options.getAddressOption())
             builder.setAddresses(HostAddresses.getLocalAddresses());
 
+        builder.setTill(options.lifetime);
+        builder.setRTime(options.renewable_lifetime);
+
         builder.action();
 
         sun.security.krb5.internal.ccache.Credentials credentials =
diff --git a/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java b/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java
index e7507a0..23bfeca 100644
--- a/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java
+++ b/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java
@@ -33,12 +33,8 @@
 import sun.security.krb5.*;
 import sun.security.krb5.internal.*;
 import sun.security.krb5.internal.ccache.*;
-import java.io.File;
 import java.io.IOException;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
+import java.time.Instant;
 import java.io.FileInputStream;
 
 /**
@@ -49,14 +45,15 @@
  * @author Ram Marti
  */
 class KinitOptions {
-    public boolean validate = false;
+
+    // 1. acquire, 2. renew, 3. validate
+    public int action = 1;
 
     // forwardable and proxiable flags have two states:
     // -1 - flag set to be not forwardable or proxiable;
     // 1 - flag set to be forwardable or proxiable.
-    public short forwardable = -1;
-    public short proxiable = -1;
-    public boolean renew = false;
+    public short forwardable = 0;
+    public short proxiable = 0;
     public KerberosTime lifetime;
     public KerberosTime renewable_lifetime;
     public String target_service;
@@ -134,6 +131,12 @@
                 }
 
                 useKeytab = true;
+            } else if (args[i].equals("-R")) {
+                action = 2;
+            } else if (args[i].equals("-l")) {
+                lifetime = getTime(Config.duration(args[++i]));
+            } else if (args[i].equals("-r")) {
+                renewable_lifetime = getTime(Config.duration(args[++i]));
             } else if (args[i].equalsIgnoreCase("-help")) {
                 printHelp();
                 System.exit(0);
@@ -223,23 +226,28 @@
 
 
     void printHelp() {
-        System.out.println("Usage: kinit " +
-                           "[-A] [-f] [-p] [-c cachename] " +
-                           "[[-k [-t keytab_file_name]] [principal] " +
+        System.out.println("Usage:\n\n1. Initial ticket request:\n" +
+                "    kinit [-A] [-f] [-p] [-c cachename] " +
+                "[-l lifetime] [-r renewable_time]\n" +
+                "          [[-k [-t keytab_file_name]] [principal] " +
                            "[password]");
-        System.out.println("\tavailable options to " +
+        System.out.println("2. Renew a ticket:\n" +
+                "    kinit -R [-c cachename] [principal]");
+        System.out.println("\nAvailable options to " +
                            "Kerberos 5 ticket request:");
-        System.out.println("\t    -A   do not include addresses");
-        System.out.println("\t    -f   forwardable");
-        System.out.println("\t    -p   proxiable");
-        System.out.println("\t    -c   cache name " +
-                           "(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)");
-        System.out.println("\t    -k   use keytab");
-        System.out.println("\t    -t   keytab file name");
-        System.out.println("\t    principal   the principal name "+
-                           "(i.e., qweadf@ATHENA.MIT.EDU qweadf)");
-        System.out.println("\t    password   " +
-                           "the principal's Kerberos password");
+        System.out.println("\t-A   do not include addresses");
+        System.out.println("\t-f   forwardable");
+        System.out.println("\t-p   proxiable");
+        System.out.println("\t-c   cache name " +
+                "(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)");
+        System.out.println("\t-l   lifetime");
+        System.out.println("\t-r   renewable time " +
+                "(total lifetime a ticket can be renewed)");
+        System.out.println("\t-k   use keytab");
+        System.out.println("\t-t   keytab file name");
+        System.out.println("\tprincipal   the principal name "+
+                "(i.e., qweadf@ATHENA.MIT.EDU qweadf)");
+        System.out.println("\tpassword    the principal's Kerberos password");
     }
 
     public boolean getAddressOption() {
@@ -257,4 +265,8 @@
     public PrincipalName getPrincipal() {
         return principal;
     }
+
+    private KerberosTime getTime(int s) {
+        return new KerberosTime(Instant.now().plusSeconds(s));
+    }
 }
diff --git a/src/windows/native/java/lang/ProcessImpl_md.c b/src/windows/native/java/lang/ProcessImpl_md.c
index 3a013c1..8dcf897 100644
--- a/src/windows/native/java/lang/ProcessImpl_md.c
+++ b/src/windows/native/java/lang/ProcessImpl_md.c
@@ -421,10 +421,10 @@
 Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env,
                                                        jclass ignored,
                                                        jlong handle,
-                                                       jlong timeout)
+                                                       jlong timeoutMillis)
 {
     HANDLE events[2];
-    DWORD dwTimeout = (DWORD)timeout;
+    DWORD dwTimeout = (DWORD)timeoutMillis;
     DWORD result;
     events[0] = (HANDLE) handle;
     events[1] = JVM_GetThreadInterruptEvent();
diff --git a/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp b/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp
index 1615a6e..1928694 100644
--- a/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp
+++ b/src/windows/native/sun/bridge/AccessBridgeATInstance.cpp
@@ -53,17 +53,17 @@
  * AccessBridgeATInstance descructor
  */
 AccessBridgeATInstance::~AccessBridgeATInstance() {
-    PrintDebugString("\r\nin AccessBridgeATInstance::~AccessBridgeATInstance");
+    PrintDebugString("[INFO]: in AccessBridgeATInstance::~AccessBridgeATInstance");
 
     // if IPC memory mapped file view is valid, unmap it
     if (memoryMappedView != (char *) 0) {
-        PrintDebugString("  unmapping memoryMappedView; view = %p", memoryMappedView);
+        PrintDebugString("[INFO]:   unmapping memoryMappedView; view = %p", memoryMappedView);
         UnmapViewOfFile(memoryMappedView);
         memoryMappedView = (char *) 0;
     }
     // if IPC memory mapped file handle map is open, close it
     if (memoryMappedFileMapHandle != (HANDLE) 0) {
-        PrintDebugString("  closing memoryMappedFileMapHandle; handle = %p", memoryMappedFileMapHandle);
+        PrintDebugString("[INFO]:   closing memoryMappedFileMapHandle; handle = %p", memoryMappedFileMapHandle);
         CloseHandle(memoryMappedFileMapHandle);
         memoryMappedFileMapHandle = (HANDLE) 0;
     }
@@ -87,7 +87,7 @@
 AccessBridgeATInstance::initiateIPC() {
     DWORD errorCode;
 
-    PrintDebugString("\r\nin AccessBridgeATInstance::initiateIPC()");
+    PrintDebugString("[INFO]: In AccessBridgeATInstance::initiateIPC()");
 
     // open Windows-initiated IPC filemap & map it to a ptr
 
@@ -95,10 +95,10 @@
                                                 FALSE, memoryMappedFileName);
     if (memoryMappedFileMapHandle == NULL) {
         errorCode = GetLastError();
-        PrintDebugString("  Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode);
+        PrintDebugString("[ERROR]:   Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode);
         return errorCode;
     } else {
-        PrintDebugString("  CreateFileMapping worked - filename: %s", memoryMappedFileName);
+        PrintDebugString("[INFO]:   CreateFileMapping worked - filename: %s", memoryMappedFileName);
     }
 
     memoryMappedView = (char *) MapViewOfFile(memoryMappedFileMapHandle,
@@ -106,20 +106,20 @@
                                               0, 0, 0);
     if (memoryMappedView == NULL) {
         errorCode = GetLastError();
-        PrintDebugString("  Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode);
+        PrintDebugString("[ERROR]:   Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode);
         return errorCode;
     } else {
-        PrintDebugString("  MapViewOfFile worked - view: %p", memoryMappedView);
+        PrintDebugString("[INFO]:   MapViewOfFile worked - view: %p", memoryMappedView);
     }
 
 
     // look for the JavaDLL's answer to see if it could read the file
     if (strcmp(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_QUERY) != 0) {
-        PrintDebugString("  JavaVM failed to write to memory mapped file %s",
+        PrintDebugString("[ERROR]:   JavaVM failed to write to memory mapped file %s",
                          memoryMappedFileName);
         return -1;
     } else {
-        PrintDebugString("  JavaVM successfully wrote to file!");
+        PrintDebugString("[INFO]:   JavaVM successfully wrote to file!");
     }
 
 
@@ -213,8 +213,8 @@
 LRESULT
 AccessBridgeATInstance::sendJavaEventPackage(char *buffer, int bufsize, long eventID) {
 
-    PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() eventID = %X", eventID);
-    PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() (using PostMessage) eventID = %X", eventID);
+    PrintDebugString("[INFO]: AccessBridgeATInstance::sendJavaEventPackage() eventID = %X", eventID);
+    PrintDebugString("[INFO]: AccessBridgeATInstance::sendJavaEventPackage() (using PostMessage) eventID = %X", eventID);
 
     if (eventID & javaEventMask) {
         do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow);
@@ -234,7 +234,7 @@
 LRESULT
 AccessBridgeATInstance::sendAccessibilityEventPackage(char *buffer, int bufsize, long eventID) {
 
-    PrintDebugString("AccessBridgeATInstance::sendAccessibilityEventPackage() eventID = %X", eventID);
+    PrintDebugString("[INFO]: AccessBridgeATInstance::sendAccessibilityEventPackage() eventID = %X", eventID);
 
     if (eventID & accessibilityEventMask) {
         do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow);
diff --git a/src/windows/native/sun/bridge/AccessBridgeDebug.cpp b/src/windows/native/sun/bridge/AccessBridgeDebug.cpp
index db0ec97..9640ba2 100644
--- a/src/windows/native/sun/bridge/AccessBridgeDebug.cpp
+++ b/src/windows/native/sun/bridge/AccessBridgeDebug.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -31,17 +31,66 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <windows.h>
+#include <cstdlib>
+#include <cstring>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+static FILE* logFP = nullptr;
+
+void initializeFileLogger(char * fileName) {
+    auto var = "JAVA_ACCESSBRIDGE_LOGDIR";
+    const auto envfilePath = getenv(var);
+    if (envfilePath != nullptr && fileName != nullptr) {
+        auto envFilePathLength = strlen(envfilePath);
+        auto fileNameLength = strlen(fileName);
+        auto filePathSize = envFilePathLength + 1 + fileNameLength + 5; //1 for "/", 5 for ".log" and 0;
+        auto filePath = new char[filePathSize];
+        memset(filePath, 0, filePathSize*sizeof(char));
+        memcpy(filePath, envfilePath, envFilePathLength*sizeof(char));
+        filePath[envFilePathLength] = '/';
+        memcpy(filePath + envFilePathLength + 1, fileName, fileNameLength*sizeof(char));
+        memcpy(filePath + envFilePathLength + 1 + fileNameLength, ".log", 4*sizeof(char));
+
+        logFP = fopen(filePath, "w");
+        if (logFP == nullptr) {
+            printf("\n%s\n", filePath);
+            PrintDebugString("Could not open file %s", filePath);
+        }
+
+        delete [] filePath;
+    }
+}
+
+void finalizeFileLogger() {
+    if (logFP) {
+        fclose(logFP);
+        logFP = nullptr;
+    }
+}
+
+auto getTimeStamp() -> long long {
+    LARGE_INTEGER freqLarge;
+    ::QueryPerformanceFrequency(&freqLarge);
+    long long freq = freqLarge.QuadPart;
+    LARGE_INTEGER counterLarge;
+    ::QueryPerformanceCounter(&counterLarge);
+    long long counter = counterLarge.QuadPart;
+    long long milliDen = 1000;
+    // prevent possible overflow
+    long long whole = (counter / freq) * milliDen;
+    long long part = (counter % freq) * milliDen / freq;
+    return whole + part;
+}
+
     /**
      * Send debugging info to the appropriate place
      */
     void PrintDebugString(char *msg, ...) {
 #ifdef DEBUGGING_ON
-        char buf[1024];
+        char buf[1024] = {0};
         va_list argprt;
 
         va_start(argprt, msg);     // set up argptr
@@ -54,6 +103,14 @@
         printf("\r\n");
 #endif
 #endif
+        if (logFP) {
+            fprintf(logFP, "[%llu] ", getTimeStamp());
+            va_list args;
+            va_start(args, msg);
+            vfprintf(logFP, msg, args);
+            va_end(args);
+            fprintf(logFP, "\r\n");
+        }
     }
 
     /**
@@ -61,7 +118,7 @@
      */
     void PrintJavaDebugString2(char *msg, ...) {
 #ifdef JAVA_DEBUGGING_ON
-        char buf[1024];
+        char buf[1024] = {0};
         va_list argprt;
 
         va_start(argprt, msg);     // set up argptr
@@ -74,13 +131,21 @@
         printf("\r\n");
 #endif
 #endif
+        if (logFP) {
+            fprintf(logFP, "[%llu] ", getTimeStamp());
+            va_list args;
+            va_start(args, msg);
+            vfprintf(logFP, msg, args);
+            va_end(args);
+            fprintf(logFP, "\r\n");
+        }
     }
     /**
      * Wide version of the method to send debugging info to the appropriate place
      */
     void wPrintDebugString(wchar_t *msg, ...) {
 #ifdef DEBUGGING_ON
-        char buf[1024];
+        char buf[1024] = {0};
         char charmsg[256];
         va_list argprt;
 
@@ -95,6 +160,14 @@
         printf("\r\n");
 #endif
 #endif
+        if (logFP) {
+            fprintf(logFP, "[%llu] ", getTimeStamp());
+            va_list args;
+            va_start(args, msg);
+            vfwprintf(logFP, msg, args);
+            va_end(args);
+            fprintf(logFP, "\r\n");
+        }
     }
 
     /**
@@ -102,8 +175,8 @@
      */
     void wPrintJavaDebugString(wchar_t *msg, ...) {
 #ifdef JAVA_DEBUGGING_ON
-        char buf[1024];
-        char charmsg[256];
+        char buf[1024] = {0};
+        char charmsg[256] = {0};
         va_list argprt;
 
         va_start(argprt, msg);          // set up argptr
@@ -117,6 +190,14 @@
         printf("\r\n");
 #endif
 #endif
+        if (logFP) {
+            fprintf(logFP, "[%llu] ", getTimeStamp());
+            va_list args;
+            va_start(args, msg);
+            vfwprintf(logFP, msg, args);
+            va_end(args);
+            fprintf(logFP, "\r\n");
+        }
     }
 #ifdef __cplusplus
 }
diff --git a/src/windows/native/sun/bridge/AccessBridgeDebug.h b/src/windows/native/sun/bridge/AccessBridgeDebug.h
index 4e1ce05..217a529 100644
--- a/src/windows/native/sun/bridge/AccessBridgeDebug.h
+++ b/src/windows/native/sun/bridge/AccessBridgeDebug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -53,6 +53,8 @@
     void PrintJavaDebugString(char *msg, ...);
     void wPrintJavaDebugString(wchar_t *msg, ...);
     void wPrintDebugString(wchar_t *msg, ...);
+    void initializeFileLogger(char * fileName);
+    void finalizeFileLogger();
 
 #ifdef __cplusplus
 }
diff --git a/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp b/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp
index ee75bfe..e16192a 100644
--- a/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp
+++ b/src/windows/native/sun/bridge/AccessBridgeEventHandler.cpp
@@ -170,7 +170,7 @@
     if (propertyChangeFP != (AccessBridge_PropertyChangeFP) 0) {
         propertyChangeFP(vmID, event, source, property, oldName, newName);
     } else {
-        DEBUG_CODE(AppendToCallInfo("  Error! propertyChangeFP == 0\r\n"));
+        DEBUG_CODE(AppendToCallInfo("[ERROR]: propertyChangeFP == 0"));
     }
 }
 
@@ -186,9 +186,9 @@
  *
  */
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%p, %p); vmID = %X\r\n";
+const char fireEventDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s(%p, %p); vmID = %X\r\n";
 #else // JOBJECT64 is jlong (64 bit)
-const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%016I64X, %016I64X); vmID = %X\r\n";
+const char fireEventDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s(%016I64X, %016I64X); vmID = %X\r\n";
 #endif
 
 #define FIRE_EVENT(method, FPprototype, eventFP) \
@@ -199,18 +199,18 @@
         if (eventFP != (FPprototype) 0) { \
             eventFP(vmID, event, source); \
         } else { \
-            DEBUG_CODE(AppendToCallInfo("  Error! eventFP == 0\r\n")); \
+            DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0")); \
         } \
     }
 
     void AccessBridgeEventHandler::fireJavaShutdown(long vmID) {
         DEBUG_CODE(char debugBuf[255]);
-        DEBUG_CODE(sprintf(debugBuf, "\r\nCalling fireJavaShutdown; vmID = %X\r\n", vmID));
+        DEBUG_CODE(sprintf(debugBuf, "[INFO]: Calling fireJavaShutdown; vmID = %X\r\n", vmID));
         DEBUG_CODE(AppendToCallInfo(debugBuf));
         if (javaShutdownFP != (AccessBridge_JavaShutdownFP) 0) {
             javaShutdownFP(vmID);
         } else {
-            DEBUG_CODE(AppendToCallInfo("  Error! javaShutdownFP == 0\r\n"));
+            DEBUG_CODE(AppendToCallInfo("[ERROR]:  javaShutdownFP == 0"));
         }
     }
 
@@ -241,9 +241,9 @@
  *
  */
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%p, %p):\r\n";
+const char firePropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a no-param property change (%p, %p):\r\n";
 #else // JOBJECT64 is jlong (64 bit)
-const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%016I64X, %016I64X):\r\n";
+const char firePropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a no-param property change (%016I64X, %016I64X):\r\n";
 #endif
 
 #define FIRE_PROPERTY_CHANGE(method, FPprototype, eventFP) \
@@ -254,7 +254,7 @@
         if (eventFP != (FPprototype) 0) { \
             eventFP(vmID, event, source); \
         } else { \
-            DEBUG_CODE(AppendToCallInfo("  Error! eventFP == 0\r\n")); \
+            DEBUG_CODE(AppendToCallInfo("[ERROR]:  eventFP == 0")); \
         } \
     }
 
@@ -269,9 +269,9 @@
  *
  */
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%p, %p, %ls, %ls):\r\n";
+const char fireStringPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a string property change (%p, %p, %ls, %ls):\r\n";
 #else // JOBJECT64 is jlong (64 bit)
-const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%016I64X, %016I64X, %ls, %ls):\r\n";
+const char fireStringPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a string property change (%016I64X, %016I64X, %ls, %ls):\r\n";
 #endif
 
 #define FIRE_STRING_PROPERTY_CHANGE(method, FPprototype, eventFP, oldValue, newValue) \
@@ -283,7 +283,7 @@
         if (eventFP != (FPprototype) 0) { \
             eventFP(vmID, event, source, oldValue, newValue); \
         } else { \
-            DEBUG_CODE(AppendToCallInfo("  Error! eventFP == 0\r\n")); \
+            DEBUG_CODE(AppendToCallInfo("[ERROR]:  eventFP == 0\r\n")); \
         } \
     }
 
@@ -298,9 +298,9 @@
  *
  */
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%p, %p, %d, %d):\r\n";
+const char fireIntPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an int property change (%p, %p, %d, %d):\r\n";
 #else // JOBJECT64 is jlong (64 bit)
-const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%016I64X, %016I64X, %d, %d):\r\n";
+const char fireIntPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an int property change (%016I64X, %016I64X, %d, %d):\r\n";
 #endif
 
 #define FIRE_INT_PROPERTY_CHANGE(method, FPprototype, eventFP) \
@@ -312,7 +312,7 @@
         if (eventFP != (FPprototype) 0) { \
             eventFP(vmID, event, source, oldValue, newValue); \
         } else { \
-            DEBUG_CODE(AppendToCallInfo("  Error! eventFP == 0\r\n")); \
+            DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0\r\n")); \
         } \
     }
 
@@ -327,9 +327,9 @@
  *
  */
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%p, %p, %p, %p):\r\n";
+const char fireACPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an AC property change (%p, %p, %p, %p):\r\n";
 #else // JOBJECT64 is jlong (64 bit)
-const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%016I64X, %016I64X, %016I64X, %016I64X):\r\n";
+const char fireACPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an AC property change (%016I64X, %016I64X, %016I64X, %016I64X):\r\n";
 #endif
 
 #define FIRE_AC_PROPERTY_CHANGE(method, FPprototype, eventFP) \
@@ -341,7 +341,7 @@
         if (eventFP != (FPprototype) 0) { \
             eventFP(vmID, event, source, oldValue, newValue); \
         } else { \
-            DEBUG_CODE(AppendToCallInfo("  Error! eventFP == 0\r\n")); \
+            DEBUG_CODE(AppendToCallInfo("[ERROR]:  eventFP == 0\r\n")); \
         } \
     }
 
diff --git a/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp b/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp
index 2d2eb88..9c19f50 100644
--- a/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp
+++ b/src/windows/native/sun/bridge/AccessBridgeJavaEntryPoints.cpp
@@ -40,7 +40,7 @@
                                                          jobject bridgeObject) {
     jniEnv = jniEnvironment;
     accessBridgeObject = (jobject)bridgeObject;
-    PrintDebugString("AccessBridgeJavaEntryPoints(%X, %X) called", jniEnv, accessBridgeObject);
+    PrintDebugString("[INFO]: AccessBridgeJavaEntryPoints(%p, %p) called", jniEnv, accessBridgeObject);
 }
 
 
@@ -56,15 +56,13 @@
 #define FIND_CLASS(classRef, className) \
     localClassRef = jniEnv->FindClass(className); \
     if (localClassRef == (jclass) 0) { \
-        PrintDebugString("  Error! FindClass(%s) failed!", className); \
-        PrintDebugString("    -> jniEnv = %p", jniEnv); \
+        PrintDebugString("[ERROR]:  FindClass(%s) failed! -> jniEnv = %p", className, jniEnv); \
         return FALSE; \
     } \
     classRef = (jclass) jniEnv->NewGlobalRef(localClassRef); \
     jniEnv->DeleteLocalRef(localClassRef); \
     if (classRef == (jclass) 0) { \
-        PrintDebugString("  Error! FindClass(%s) failed!", className); \
-        PrintDebugString("    ->  (ran out of RAM)"); \
+        PrintDebugString("[ERROR]: FindClass(%s) failed! ->  (ran out of RAM)", className); \
         return FALSE; \
     }
 
@@ -72,14 +70,13 @@
 #define FIND_METHOD(methodID, classRef, methodString, methodSignature); \
     methodID = jniEnv->GetMethodID(classRef, methodString,  methodSignature); \
     if (methodID == (jmethodID) 0) { \
-        PrintDebugString("  Error! GetMethodID(%s) failed!", methodString); \
-        PrintDebugString("    -> jniEnv = %p; classRef = %p", jniEnv, classRef); \
+        PrintDebugString("[ERROR]: GetMethodID(%s) failed! -> jniEnv = %p; classRef = %p", methodString, jniEnv, classRef); \
         return FALSE; \
     }
 
 #define EXCEPTION_CHECK(situationDescription, returnVal)                                        \
     if (exception = jniEnv->ExceptionOccurred()) {                                              \
-        PrintDebugString("\r\n *** Exception occured while doing: %s; returning %d", situationDescription, returnVal);   \
+        PrintDebugString("[ERROR]: *** Exception occured while doing: %s; returning %d", situationDescription, returnVal);   \
         jniEnv->ExceptionDescribe();                                                            \
         jniEnv->ExceptionClear();                                                               \
         return (returnVal);                                                                     \
@@ -87,7 +84,7 @@
 
 #define EXCEPTION_CHECK_VOID(situationDescription)                                              \
     if (exception = jniEnv->ExceptionOccurred()) {                                              \
-        PrintDebugString("\r\n *** Exception occured while doing: %s", situationDescription);   \
+        PrintDebugString("[ERROR]: *** Exception occured while doing: %s", situationDescription);   \
         jniEnv->ExceptionDescribe();                                                            \
         jniEnv->ExceptionClear();                                                               \
         return;                                                                                 \
@@ -101,7 +98,7 @@
 AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() {
     jclass localClassRef;
 
-    PrintDebugString("Calling BuildJavaEntryPoints():");
+    PrintDebugString("[INFO]: Calling BuildJavaEntryPoints():");
 
     FIND_CLASS(bridgeClass, "com/sun/java/accessibility/AccessBridge");
 
@@ -886,14 +883,14 @@
     jthrowable exception;
     BOOL returnVal;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window);
 
     if (isJavaWindowMethod != (jmethodID) 0) {
         returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, isJavaWindowMethod, window);
         EXCEPTION_CHECK("Getting isJavaWindow - call to CallBooleanMethod()", FALSE);
         return returnVal;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or isJavaWindowMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or isJavaWindowMethod == 0");
         return FALSE;
     }
 }
@@ -909,12 +906,12 @@
     jthrowable exception;
     BOOL returnVal;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2);
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2);
 
     returnVal = (BOOL) jniEnv->IsSameObject((jobject)obj1, (jobject)obj2);
     EXCEPTION_CHECK("Calling IsSameObject", FALSE);
 
-    PrintDebugString("\r\n  isSameObject returning %d", returnVal);
+    PrintDebugString("[INFO]:   isSameObject returning %d", returnVal);
     return returnVal;
 }
 
@@ -930,7 +927,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window);
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window);
 
     if (getAccessibleContextFromHWNDMethod != (jmethodID) 0) {
         returnedAccessibleContext =
@@ -941,7 +938,7 @@
         EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0);
         return globalRef;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0");
+        PrintDebugString("[ERROR]:  either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0");
         return (jobject) 0;
     }
 }
@@ -957,17 +954,17 @@
     jthrowable exception;
     HWND rHWND;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):",
                      accessibleContext);
 
     if (getHWNDFromAccessibleContextMethod != (jmethodID) 0) {
         rHWND = (HWND)jniEnv->CallIntMethod(accessBridgeObject, getHWNDFromAccessibleContextMethod,
                                             accessibleContext);
         EXCEPTION_CHECK("Getting HWNDFromAccessibleContext - call to CallIntMethod()", (HWND)0);
-        PrintDebugString("\r\n    rHWND = %X", rHWND);
+        PrintDebugString("[INFO]: rHWND = %X", rHWND);
         return rHWND;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0");
         return (HWND)0;
     }
 }
@@ -983,7 +980,7 @@
     jthrowable exception;
     BOOL result = FALSE;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):",
                      accessibleContext, text);
 
     if (setTextContentsMethod != (jmethodID) 0) {
@@ -991,7 +988,7 @@
         // create a Java String for the text
         jstring textString = jniEnv->NewString(text, (jsize)wcslen(text));
         if (textString == 0) {
-            PrintDebugString("\r    NewString failed");
+            PrintDebugString("[ERROR]:    NewString failed");
             return FALSE;
         }
 
@@ -999,10 +996,10 @@
                                                  setTextContentsMethod,
                                                  accessibleContext, textString);
         EXCEPTION_CHECK("setTextContents - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("\r\n    result = %d", result);
+        PrintDebugString("[INFO]:     result = %d", result);
         return result;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or setTextContentsMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or setTextContentsMethod == 0");
         return result;
     }
 }
@@ -1020,14 +1017,14 @@
     jthrowable exception;
     jobject rAccessibleContext;
 
-    PrintDebugString("In AccessBridgeJavaEntryPoints::getParentWithRole(%p):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRole(%p):",
                      accessibleContext);
 
     if (getParentWithRoleMethod != (jmethodID) 0) {
         // create a Java String for the role
         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
         if (roleName == 0) {
-            PrintDebugString("    NewString failed");
+            PrintDebugString("[ERROR]:     NewString failed");
             return FALSE;
         }
 
@@ -1035,14 +1032,14 @@
                                                       getParentWithRoleMethod,
                                                       accessibleContext, roleName);
         EXCEPTION_CHECK("Getting ParentWithRole - call to CallObjectMethod()", (AccessibleContext)0);
-        PrintDebugString("    rAccessibleContext = %p", rAccessibleContext);
+        PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
         EXCEPTION_CHECK("Getting ParentWithRole - call to NewGlobalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          rAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getParentWithRoleMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or getParentWithRoleMethod == 0");
         return 0;
     }
 }
@@ -1058,7 +1055,7 @@
     jthrowable exception;
     jobject rAccessibleContext;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTopLevelObject(%p):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTopLevelObject(%p):",
                      accessibleContext);
 
     if (getTopLevelObjectMethod != (jmethodID) 0) {
@@ -1066,14 +1063,14 @@
                                                       getTopLevelObjectMethod,
                                                       accessibleContext);
         EXCEPTION_CHECK("Getting TopLevelObject - call to CallObjectMethod()", FALSE);
-        PrintDebugString("\r\n    rAccessibleContext = %p", rAccessibleContext);
+        PrintDebugString("[INFO]:  rAccessibleContext = %p", rAccessibleContext);
         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
         EXCEPTION_CHECK("Getting TopLevelObject - call to NewGlobalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          rAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getTopLevelObjectMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or getTopLevelObjectMethod == 0");
         return 0;
     }
 }
@@ -1089,7 +1086,7 @@
     jthrowable exception;
     jobject rAccessibleContext;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):",
                      accessibleContext);
 
     if (getParentWithRoleElseRootMethod != (jmethodID) 0) {
@@ -1097,7 +1094,7 @@
         // create a Java String for the role
         jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role));
         if (roleName == 0) {
-            PrintDebugString("\r    NewString failed");
+            PrintDebugString("[ERROR]:     NewString failed");
             return FALSE;
         }
 
@@ -1105,14 +1102,14 @@
                                                       getParentWithRoleElseRootMethod,
                                                       accessibleContext, roleName);
         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to CallObjectMethod()", (AccessibleContext)0);
-        PrintDebugString("    rAccessibleContext = %p", rAccessibleContext);
+        PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
         EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to NewGlobalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          rAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getParentWithRoleElseRootMethod == 0");
+        PrintDebugString("[ERROR]:  either jniEnv == 0 or getParentWithRoleElseRootMethod == 0");
         return 0;
     }
 }
@@ -1127,7 +1124,7 @@
     jthrowable exception;
     jint rResult;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getObjectDepth(%p):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getObjectDepth(%p):",
                      accessibleContext);
 
     if (getObjectDepthMethod != (jmethodID) 0) {
@@ -1135,10 +1132,10 @@
                                         getObjectDepthMethod,
                                         accessibleContext);
         EXCEPTION_CHECK("Getting ObjectDepth - call to CallIntMethod()", -1);
-        PrintDebugString("\r\n    rResult = %d", rResult);
+        PrintDebugString("[INFO]:     rResult = %d", rResult);
         return rResult;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getObjectDepthMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or getObjectDepthMethod == 0");
         return -1;
     }
 }
@@ -1154,7 +1151,7 @@
     jthrowable exception;
     jobject rAccessibleContext;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getActiveDescendent(%p):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getActiveDescendent(%p):",
                      accessibleContext);
 
     if (getActiveDescendentMethod != (jmethodID) 0) {
@@ -1162,14 +1159,14 @@
                                                       getActiveDescendentMethod,
                                                       accessibleContext);
         EXCEPTION_CHECK("Getting ActiveDescendent - call to CallObjectMethod()", (AccessibleContext)0);
-        PrintDebugString("\r\n    rAccessibleContext = %p", rAccessibleContext);
+        PrintDebugString("[INFO]:     rAccessibleContext = %p", rAccessibleContext);
         jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext);
         EXCEPTION_CHECK("Getting ActiveDescendant - call to NewGlobalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          rAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getActiveDescendentMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or getActiveDescendentMethod == 0");
         return (AccessibleContext)0;
     }
 }
@@ -1210,7 +1207,7 @@
     const wchar_t * stringBytes = NULL;
     jthrowable exception = NULL;
     jsize length = 0;
-    PrintDebugString("\r\n  getVirtualAccessibleName called.");
+    PrintDebugString("[INFO]:  getVirtualAccessibleName called.");
     if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0)
     {
         js = (jstring) jniEnv->CallObjectMethod (
@@ -1231,18 +1228,18 @@
                 accessBridgeObject,
                 decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Name = %ls", name);
+            wPrintDebugString(L"[INFO]:  Accessible Name = %ls", name);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
         }
         else
         {
-            PrintDebugString("  Accessible Name is null.");
+            PrintDebugString("[INFO]:   Accessible Name is null.");
         }
     }
     else
     {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0");
+        PrintDebugString("[INFO]: either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0");
         return FALSE;
     }
     if ( 0 != name [0] )
@@ -1264,7 +1261,7 @@
     jthrowable exception;
     BOOL result = FALSE;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::requestFocus(%p):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::requestFocus(%p):",
                      accessibleContext);
 
     if (requestFocusMethod != (jmethodID) 0) {
@@ -1272,10 +1269,10 @@
                                                  requestFocusMethod,
                                                  accessibleContext);
         EXCEPTION_CHECK("requestFocus - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("\r\n    result = %d", result);
+        PrintDebugString("[INFO]:    result = %d", result);
         return result;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or requestFocusMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or requestFocusMethod == 0");
         return result;
     }
 }
@@ -1292,7 +1289,7 @@
     jthrowable exception;
     BOOL result = FALSE;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):",
                      accessibleContext, startIndex, endIndex);
 
     if (selectTextRangeMethod != (jmethodID) 0) {
@@ -1301,10 +1298,10 @@
                                                  accessibleContext,
                                                  startIndex, endIndex);
         EXCEPTION_CHECK("selectTextRange - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("\r\n    result = %d", result);
+        PrintDebugString("[INFO]:     result = %d", result);
         return result;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or selectTextRangeMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or selectTextRangeMethod == 0");
         return result;
     }
 }
@@ -1361,7 +1358,7 @@
     jsize length;
     BOOL result = FALSE;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):",
                      accessibleContext, startIndex, endIndex);
 
     *len = 0;
@@ -1376,12 +1373,12 @@
         AccessibleTextAttributesInfo test_attributes = *attributes;
         // Get the full test_attributes string at i
         if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
-            PrintDebugString(" Getting full test_attributes string from Context...");
+            PrintDebugString("[INFO]:  Getting full test_attributes string from Context...");
             js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
                                                     getAccessibleAttributesAtIndexFromContextMethod,
                                                     accessibleContext, i);
             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
-            PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+            PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
             if (js != (jstring) 0) {
                 stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
@@ -1395,16 +1392,16 @@
                 jniEnv->CallVoidMethod(accessBridgeObject,
                                        decrementReferenceMethod, js);
                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
-                wPrintDebugString(L"  Accessible Text attributes = %ls", test_attributes.fullAttributesString);
+                wPrintDebugString(L"[INFO]:  Accessible Text attributes = %ls", test_attributes.fullAttributesString);
                 jniEnv->DeleteLocalRef(js);
                 EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
             } else {
-                PrintDebugString("  Accessible Text attributes is null.");
+                PrintDebugString("[WARN]:   Accessible Text attributes is null.");
                 test_attributes.fullAttributesString[0] = (wchar_t) 0;
                 return FALSE;
             }
         } else {
-            PrintDebugString("  Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
+            PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
             return FALSE;
         }
 
@@ -1427,14 +1424,14 @@
 AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) {
 
     jthrowable exception;
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)",
                      accessibleContext);
 
     // get the visible children count
     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
                                             accessibleContext);
     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### visible children count = %d", numChildren);
+    PrintDebugString("[INFO]:   ##### visible children count = %d", numChildren);
 
     return numChildren;
 }
@@ -1454,14 +1451,14 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)",
                      accessibleContext, nStartIndex);
 
     // get the visible children count
     int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod,
                                             accessibleContext);
     EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### visible children count = %d", numChildren);
+    PrintDebugString("[INFO]:   ##### visible children count = %d", numChildren);
 
     if (nStartIndex >= numChildren) {
         return FALSE;
@@ -1470,7 +1467,7 @@
     // get the visible children
     int bufIndex = 0;
     for (int i = nStartIndex; (i < numChildren) && (i < nStartIndex + MAX_VISIBLE_CHILDREN); i++) {
-        PrintDebugString("  getting visible child %d ...", i);
+        PrintDebugString("[INFO]:   getting visible child %d ...", i);
 
         // get the visible child at index i
         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getVisibleChildMethod,
@@ -1479,13 +1476,13 @@
         jobject globalRef = jniEnv->NewGlobalRef(ac);
         EXCEPTION_CHECK("##### getVisibleChildMethod - call to NewGlobalRef()", FALSE);
         visibleChildrenInfo->children[bufIndex] = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### visible child = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### visible child = %p", globalRef);
 
         bufIndex++;
     }
     visibleChildrenInfo->returnedChildrenCount = bufIndex;
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded");
+    PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded");
     return TRUE;
 }
 
@@ -1500,7 +1497,7 @@
     jthrowable exception;
     BOOL result = FALSE;
 
-    PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):",
+    PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):",
                      accessibleContext, position);
 
     if (setCaretPositionMethod != (jmethodID) 0) {
@@ -1508,10 +1505,10 @@
                                                  setCaretPositionMethod,
                                                  accessibleContext, position);
         EXCEPTION_CHECK("setCaretPostion - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("\r\n    result = %d", result);
+        PrintDebugString("[ERROR]:     result = %d", result);
         return result;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or setCaretPositionMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or setCaretPositionMethod == 0");
         return result;
     }
 }
@@ -1531,19 +1528,19 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getVersionInfo():");
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getVersionInfo():");
 
     if (getJavaVersionPropertyMethod != (jmethodID) 0) {
         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
                                                 getJavaVersionPropertyMethod);
         EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             length = jniEnv->GetStringLength(js);
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             if (stringBytes == NULL) {
                 if (!jniEnv->ExceptionCheck()) {
-                    PrintDebugString("\r\n *** Exception when getting JavaVersionProperty - call to GetStringChars");
+                    PrintDebugString("[ERROR]:  *** Exception when getting JavaVersionProperty - call to GetStringChars");
                     jniEnv->ExceptionDescribe();
                     jniEnv->ExceptionClear();
                 }
@@ -1574,16 +1571,16 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Java version = %ls", info->VMversion);
+            wPrintDebugString(L"[INFO]:  Java version = %ls", info->VMversion);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting JavaVersionProperty - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Java version is null.");
+            PrintDebugString("[WARN]:   Java version is null.");
             info->VMversion[0] = (wchar_t) 0;
             return FALSE;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getJavaVersionPropertyMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getJavaVersionPropertyMethod == 0");
         return FALSE;
     }
 
@@ -1600,15 +1597,15 @@
     BOOL retval;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::verifyAccessibleText");
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::verifyAccessibleText");
 
     if (jniEnv->GetJavaVM(&vm) != 0) {
-        PrintDebugString("  Error! No Java VM");
+        PrintDebugString("[ERROR]:  No Java VM");
         return FALSE;
     }
 
     if (obj == (jobject)0) {
-        PrintDebugString("  Error! Null jobject");
+        PrintDebugString("[ERROR]:  Null jobject");
         return FALSE;
     }
 
@@ -1618,16 +1615,16 @@
                                                            getAccessibleTextFromContextMethod,
                                                            (jobject)obj);
         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  AccessibleText = %p", returnedJobject);
+        PrintDebugString("[ERROR]:   AccessibleText = %p", returnedJobject);
         retval = returnedJobject != (jobject) 0;
         jniEnv->DeleteLocalRef(returnedJobject);
         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextFromContextMethod == 0");
         return FALSE;
     }
     if (retval == FALSE) {
-        PrintDebugString("  Error! jobject is not an AccessibleText");
+        PrintDebugString("[ERROR]:  jobject is not an AccessibleText");
     }
     return retval;
 }
@@ -1652,7 +1649,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):",
                      x, y, accessibleContext);
 
     if (getAccessibleContextAtMethod != (jmethodID) 0) {
@@ -1662,11 +1659,11 @@
         EXCEPTION_CHECK("Getting AccessibleContextAt - call to CallObjectMethod()", FALSE);
         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
         EXCEPTION_CHECK("Getting AccessibleContextAt - call to NewGlobalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          returnedAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleContextAtMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleContextAtMethod == 0");
         return (jobject) 0;
     }
 }
@@ -1687,7 +1684,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()");
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()");
 
     if (getAccessibleContextWithFocusMethod != (jmethodID) 0) {
         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
@@ -1695,11 +1692,11 @@
         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to CallObjectMethod()", FALSE);
         globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext);
         EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to NewGlobalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          returnedAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("  Error! either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0");
+        PrintDebugString("[ERROR]:  either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0");
         return (jobject) 0;
     }
 }
@@ -1724,12 +1721,12 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext);
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext);
 
     ZeroMemory(info, sizeof(AccessibleContextInfo));
 
     if (accessibleContext == (jobject) 0) {
-        PrintDebugString(" passed in AccessibleContext == null! (oops)");
+        PrintDebugString("[WARN]:  passed in AccessibleContext == null! (oops)");
         return (FALSE);
     }
 
@@ -1752,15 +1749,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Name = %ls", info->name);
+            wPrintDebugString(L"[INFO]:   Accessible Name = %ls", info->name);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Name is null.");
+            PrintDebugString("[WARN]:   Accessible Name is null.");
             info->name[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleNameFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleNameFromContextMethod == 0");
         return FALSE;
     }
 
@@ -1784,15 +1781,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Description = %ls", info->description);
+            wPrintDebugString(L"[INFO]:   Accessible Description = %ls", info->description);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Description is null.");
+            PrintDebugString("[WARN]:   Accessible Description is null.");
             info->description[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleDescriptionFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleDescriptionFromContextMethod == 0");
         return FALSE;
     }
 
@@ -1816,15 +1813,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Role = %ls", info->role);
+            wPrintDebugString(L"[INFO]:   Accessible Role = %ls", info->role);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleRole - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Role is null.");
+            PrintDebugString("[WARN]:   Accessible Role is null.");
             info->role[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleRoleStringFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleRoleStringFromContextMethod == 0");
         return FALSE;
     }
 
@@ -1848,15 +1845,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Role en_US = %ls", info->role_en_US);
+            wPrintDebugString(L"[INFO]:   Accessible Role en_US = %ls", info->role_en_US);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Role en_US is null.");
+            PrintDebugString("[WARN]:   Accessible Role en_US is null.");
             info->role[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0");
         return FALSE;
     }
 
@@ -1879,15 +1876,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible States = %ls", info->states);
+            wPrintDebugString(L"[INFO]:   Accessible States = %ls", info->states);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleState - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible States is null.");
+            PrintDebugString("[WARN]:   Accessible States is null.");
             info->states[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleStatesStringFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleStatesStringFromContextMethod == 0");
         return FALSE;
     }
 
@@ -1910,15 +1907,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible States en_US = %ls", info->states_en_US);
+            wPrintDebugString(L"[INFO]:   Accessible States en_US = %ls", info->states_en_US);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleState_en_US - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible States en_US is null.");
+            PrintDebugString("[WARN]:   Accessible States en_US is null.");
             info->states[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0");
         return FALSE;
     }
 
@@ -1929,14 +1926,14 @@
                                                     getAccessibleIndexInParentFromContextMethod,
                                                     accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleIndexInParent - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Index in Parent = %d", info->indexInParent);
+        PrintDebugString("[INFO]:   Index in Parent = %d", info->indexInParent);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleIndexInParentFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleIndexInParentFromContextMethod == 0");
         return FALSE;
     }
 
 
-    PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***",
+    PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***",
                      jniEnv, accessBridgeObject, accessibleContext);
 
     // Get the children count
@@ -1945,13 +1942,13 @@
                                                     getAccessibleChildrenCountFromContextMethod,
                                                     accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleChildrenCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Children count = %d", info->childrenCount);
+        PrintDebugString("[INFO]:   Children count = %d", info->childrenCount);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleChildrenCountFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleChildrenCountFromContextMethod == 0");
         return FALSE;
     }
 
-    PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***",
+    PrintDebugString("[INFO]: *** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***",
                      jniEnv, accessBridgeObject, accessibleContext);
 
 
@@ -1961,13 +1958,13 @@
                                         getAccessibleXcoordFromContextMethod,
                                         accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleXcoord - call to CallIntMethod()", FALSE);
-        PrintDebugString("  X coord = %d", info->x);
+        PrintDebugString("[INFO]:   X coord = %d", info->x);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleXcoordFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleXcoordFromContextMethod == 0");
         return FALSE;
     }
 
-    PrintDebugString("*** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***",
+    PrintDebugString("[INFO]: *** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***",
                      jniEnv, accessBridgeObject, accessibleContext);
 
 
@@ -1977,9 +1974,9 @@
                                         getAccessibleYcoordFromContextMethod,
                                         accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleYcoord - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Y coord = %d", info->y);
+        PrintDebugString("[INFO]:   Y coord = %d", info->y);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleYcoordFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleYcoordFromContextMethod == 0");
         return FALSE;
     }
 
@@ -1989,9 +1986,9 @@
                                             getAccessibleWidthFromContextMethod,
                                             accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleWidth - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Width = %d", info->width);
+        PrintDebugString("[INFO]:   Width = %d", info->width);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleWidthFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleWidthFromContextMethod == 0");
         return FALSE;
     }
 
@@ -2001,9 +1998,9 @@
                                              getAccessibleHeightFromContextMethod,
                                              accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleHeight - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Height = %d", info->height);
+        PrintDebugString("[INFO]:   Height = %d", info->height);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleHeightFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleHeightFromContextMethod == 0");
         return FALSE;
     }
 
@@ -2013,12 +2010,12 @@
                                                    getAccessibleComponentFromContextMethod,
                                                    accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleComponent - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  AccessibleComponent = %p", returnedJobject);
+        PrintDebugString("[INFO]:   AccessibleComponent = %p", returnedJobject);
         info->accessibleComponent = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
         jniEnv->DeleteLocalRef(returnedJobject);
         EXCEPTION_CHECK("Getting AccessibleComponent - call to DeleteLocalRef()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleComponentFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleComponentFromContextMethod == 0");
         return FALSE;
     }
 
@@ -2028,12 +2025,12 @@
                                                    getAccessibleActionFromContextMethod,
                                                    accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleAction - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  AccessibleAction = %p", returnedJobject);
+        PrintDebugString("[INFO]:   AccessibleAction = %p", returnedJobject);
         info->accessibleAction = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
         jniEnv->DeleteLocalRef(returnedJobject);
         EXCEPTION_CHECK("Getting AccessibleAction - call to DeleteLocalRef()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleActionFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleActionFromContextMethod == 0");
         return FALSE;
     }
 
@@ -2043,24 +2040,24 @@
                                                    getAccessibleSelectionFromContextMethod,
                                                    accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleSelection - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  AccessibleSelection = %p", returnedJobject);
+        PrintDebugString("[INFO]:   AccessibleSelection = %p", returnedJobject);
         info->accessibleSelection = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
         jniEnv->DeleteLocalRef(returnedJobject);
         EXCEPTION_CHECK("Getting AccessibleSelection - call to DeleteLocalRef()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleSelectionFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleSelectionFromContextMethod == 0");
         return FALSE;
     }
 
     // Get the AccessibleTable
     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
-        PrintDebugString("##### Calling getAccessibleTableFromContextMethod ...");
+        PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ...");
         returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject,
                                                    getAccessibleTableFromContextMethod,
                                                    accessibleContext);
-        PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod");
+        PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod");
         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  ##### AccessibleTable = %p", returnedJobject);
+        PrintDebugString("[INFO]:   ##### AccessibleTable = %p", returnedJobject);
         if (returnedJobject != (jobject) 0) {
             info->accessibleInterfaces |= cAccessibleTableInterface;
         }
@@ -2078,7 +2075,7 @@
         */
 
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0");
         return FALSE;
     }
 
@@ -2088,12 +2085,12 @@
                                                    getAccessibleTextFromContextMethod,
                                                    accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  AccessibleText = %p", returnedJobject);
+        PrintDebugString("[INFO]:   AccessibleText = %p", returnedJobject);
         info->accessibleText = (returnedJobject != (jobject) 0 ? TRUE : FALSE);
         jniEnv->DeleteLocalRef(returnedJobject);
         EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextFromContextMethod == 0");
         return FALSE;
     }
 
@@ -2103,14 +2100,14 @@
                                                    getAccessibleValueFromContextMethod,
                                                    accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleValue - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  AccessibleValue = %p", returnedJobject);
+        PrintDebugString("[INFO]:   AccessibleValue = %p", returnedJobject);
         if (returnedJobject != (jobject) 0) {
             info->accessibleInterfaces |= cAccessibleValueInterface;
         }
         jniEnv->DeleteLocalRef(returnedJobject);
         EXCEPTION_CHECK("Getting AccessibleValue - call to DeleteLocalRef()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleValueFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleValueFromContextMethod == 0");
         return FALSE;
     }
 
@@ -2126,7 +2123,7 @@
                                                    getAccessibleHypertextMethod,
                                                    accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleHypertext - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  AccessibleHypertext = %p",
+        PrintDebugString("[INFO]:   AccessibleHypertext = %p",
                          returnedJobject);
         if (returnedJobject != (jobject) 0) {
             info->accessibleInterfaces |= cAccessibleHypertextInterface;
@@ -2167,7 +2164,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):",
                      accessibleContext, childIndex);
 
     if (getAccessibleChildFromContextMethod != (jmethodID) 0) {
@@ -2179,11 +2176,11 @@
         EXCEPTION_CHECK("Getting AccessibleChild - call to NewGlobalRef()", FALSE);
         jniEnv->DeleteLocalRef(returnedAccessibleContext);
         EXCEPTION_CHECK("Getting AccessibleChild - call to DeleteLocalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          returnedAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleChildContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleChildContextMethod == 0");
         return (jobject) 0;
     }
 }
@@ -2199,7 +2196,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext);
 
     if (getAccessibleParentFromContextMethod != (jmethodID) 0) {
         returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject,
@@ -2210,11 +2207,11 @@
         EXCEPTION_CHECK("Getting AccessibleParent - call to NewGlobalRef()", FALSE);
         jniEnv->DeleteLocalRef(returnedAccessibleContext);
         EXCEPTION_CHECK("Getting AccessibleParent - call to DeleteLocalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          returnedAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleParentFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleParentFromContextMethod == 0");
         return (jobject) 0;
     }
 }
@@ -2228,7 +2225,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):",
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):",
                      accessibleContext);
 
     // get the table row count
@@ -2237,9 +2234,9 @@
                                                     getAccessibleTableRowCountMethod,
                                                     accessibleContext);
         EXCEPTION_CHECK("##### Getting AccessibleTableRowCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table row count = %d", tableInfo->rowCount);
+        PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleRowCountMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0");
         return FALSE;
     }
 
@@ -2249,43 +2246,43 @@
                                                        getAccessibleTableColumnCountMethod,
                                                        accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleTableColumnCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table column count = %d", tableInfo->columnCount);
+        PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnCountMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnCountMethod == 0");
         return FALSE;
     }
 
     // get the AccessibleTable
     if (getAccessibleTableFromContextMethod != (jmethodID) 0) {
-        PrintDebugString("##### Calling getAccessibleTableFromContextMethod ...");
+        PrintDebugString("[INFO]: ##### Calling getAccessibleTableFromContextMethod ...");
         jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject,
                                                     getAccessibleTableFromContextMethod,
                                                     accessibleContext);
-        PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod");
+        PrintDebugString("[INFO]: ##### ... Returned from getAccessibleTableFromContextMethod");
         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
         jobject globalRef = jniEnv->NewGlobalRef(accTable);
         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
         tableInfo->accessibleTable = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### accessibleTable = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### accessibleTable = %p", globalRef);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableFromContextMethod == 0");
         return FALSE;
     }
 
     // cache the AccessibleContext
     if (getContextFromAccessibleTableMethod != (jmethodID) 0) {
-        PrintDebugString("##### Calling getContextFromAccessibleTable Method ...");
+        PrintDebugString("[INFO]: ##### Calling getContextFromAccessibleTable Method ...");
         jobject ac = jniEnv->CallObjectMethod(accessBridgeObject,
                                               getContextFromAccessibleTableMethod,
                                               accessibleContext);
-        PrintDebugString("##### ... Returned from getContextFromAccessibleTable Method");
+        PrintDebugString("[INFO]: ##### ... Returned from getContextFromAccessibleTable Method");
         EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE);
         jobject globalRef = jniEnv->NewGlobalRef(ac);
         EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE);
         tableInfo->accessibleContext = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### accessibleContext = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### accessibleContext = %p", globalRef);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getContextFromAccessibleTable Method == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getContextFromAccessibleTable Method == 0");
         return FALSE;
     }
 
@@ -2293,7 +2290,7 @@
     tableInfo->caption = NULL;
     tableInfo->summary = NULL;
 
-    PrintDebugString("##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded");
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded");
     return TRUE;
 }
 
@@ -2303,7 +2300,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d",
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d",
                      accessibleTable, row, column);
 
     // FIX
@@ -2318,9 +2315,9 @@
                                                      getAccessibleTableCellIndexMethod,
                                                      accessibleTable, row, column);
         EXCEPTION_CHECK("##### Getting AccessibleTableCellIndex - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table cell index = %d", tableCellInfo->index);
+        PrintDebugString("[INFO]:   ##### table cell index = %d", tableCellInfo->index);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellIndexMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellIndexMethod == 0");
         return FALSE;
     }
 
@@ -2330,9 +2327,9 @@
                                                          getAccessibleTableCellRowExtentMethod,
                                                          accessibleTable, row, column);
         EXCEPTION_CHECK("##### Getting AccessibleTableCellRowExtentCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table cell row extent = %d", tableCellInfo->rowExtent);
+        PrintDebugString("[INFO]:   ##### table cell row extent = %d", tableCellInfo->rowExtent);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellRowExtentMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellRowExtentMethod == 0");
         return FALSE;
     }
 
@@ -2342,9 +2339,9 @@
                                                             getAccessibleTableCellColumnExtentMethod,
                                                             accessibleTable, row, column);
         EXCEPTION_CHECK("##### Getting AccessibleTableCellColumnExtentCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table cell column extent = %d", tableCellInfo->columnExtent);
+        PrintDebugString("[INFO]:  ##### table cell column extent = %d", tableCellInfo->columnExtent);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellColumnExtentMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellColumnExtentMethod == 0");
         return FALSE;
     }
 
@@ -2354,9 +2351,9 @@
                                                               isAccessibleTableCellSelectedMethod,
                                                               accessibleTable, row, column);
         EXCEPTION_CHECK("##### Getting isAccessibleTableCellSelected - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("  ##### table cell isSelected = %d", tableCellInfo->isSelected);
+        PrintDebugString("[INFO]:   ##### table cell isSelected = %d", tableCellInfo->isSelected);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or isAccessibleTableCellSelectedMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableCellSelectedMethod == 0");
         return FALSE;
     }
 
@@ -2369,13 +2366,13 @@
         jobject globalRef = jniEnv->NewGlobalRef(tableCellAC);
         EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to NewGlobalRef()", FALSE);
         tableCellInfo->accessibleContext = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### table cell AccessibleContext = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### table cell AccessibleContext = %p", globalRef);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0");
         return FALSE;
     }
 
-    PrintDebugString("  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded");
+    PrintDebugString("[INFO]:  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded");
     return TRUE;
 }
 
@@ -2384,7 +2381,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):",
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):",
                      acParent);
 
     // get the header row count
@@ -2393,9 +2390,9 @@
                                                     getAccessibleTableRowHeaderRowCountMethod,
                                                     acParent);
         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeaderRowCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table row count = %d", tableInfo->rowCount);
+        PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleRowHeaderRowCountMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowHeaderRowCountMethod == 0");
         return FALSE;
     }
 
@@ -2405,9 +2402,9 @@
                                                        getAccessibleTableRowHeaderColumnCountMethod,
                                                        acParent);
         EXCEPTION_CHECK("Getting AccessibleTableRowHeaderColumnCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table column count = %d", tableInfo->columnCount);
+        PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0");
         return FALSE;
     }
 
@@ -2420,9 +2417,9 @@
         jobject globalRef = jniEnv->NewGlobalRef(accTable);
         EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to NewGlobalRef()", FALSE);
         tableInfo->accessibleTable = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### row header AccessibleTable = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### row header AccessibleTable = %p", globalRef);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowHeaderMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowHeaderMethod == 0");
         return FALSE;
     }
 
@@ -2431,7 +2428,7 @@
     tableInfo->summary = NULL;
     tableInfo->accessibleContext = NULL;
 
-    PrintDebugString("  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded");
+    PrintDebugString("[INFO]:   ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded");
     return TRUE;
 }
 
@@ -2439,7 +2436,7 @@
 AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) {
     jthrowable exception;
 
-    PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):",
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):",
                      acParent);
 
     // get the header row count
@@ -2448,9 +2445,9 @@
                                                     getAccessibleTableColumnHeaderRowCountMethod,
                                                     acParent);
         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeaderRowCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table row count = %d", tableInfo->rowCount);
+        PrintDebugString("[INFO]:   ##### table row count = %d", tableInfo->rowCount);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0");
         return FALSE;
     }
 
@@ -2460,9 +2457,9 @@
                                                        getAccessibleTableColumnHeaderColumnCountMethod,
                                                        acParent);
         EXCEPTION_CHECK("Getting AccessibleTableColumnHeaderColumnCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table column count = %d", tableInfo->columnCount);
+        PrintDebugString("[INFO]:   ##### table column count = %d", tableInfo->columnCount);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0");
         return FALSE;
     }
     // get the header AccessibleTable
@@ -2474,9 +2471,9 @@
         jobject globalRef = jniEnv->NewGlobalRef(accTable);
         EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to NewGlobalRef()", FALSE);
         tableInfo->accessibleTable = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### column header AccessibleTable = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### column header AccessibleTable = %p", globalRef);
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnHeaderMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnHeaderMethod == 0");
         return FALSE;
     }
 
@@ -2485,7 +2482,7 @@
     tableInfo->summary = NULL;
     tableInfo->accessibleContext = NULL;
 
-    PrintDebugString("  ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded");
+    PrintDebugString("[INFO]:   ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded");
     return TRUE;
 }
 
@@ -2496,7 +2493,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):",
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):",
                      acParent);
 
     if (getAccessibleTableRowDescriptionMethod != (jmethodID) 0) {
@@ -2508,11 +2505,11 @@
         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to NewGlobalRef()", FALSE);
         jniEnv->DeleteLocalRef(returnedAccessibleContext);
         EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to DeleteLocalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          returnedAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTableRowDescriptionMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowDescriptionMethod == 0");
         return (jobject) 0;
     }
 }
@@ -2524,7 +2521,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):",
+    PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):",
                      acParent);
 
     if (getAccessibleTableColumnDescriptionMethod != (jmethodID) 0) {
@@ -2537,11 +2534,11 @@
         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to NewGlobalRef()", FALSE);
         jniEnv->DeleteLocalRef(returnedAccessibleContext);
         EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to DeleteLocalRef()", FALSE);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          returnedAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTableColumnDescriptionMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnDescriptionMethod == 0");
         return (jobject) 0;
     }
 }
@@ -2552,7 +2549,7 @@
     jthrowable exception;
     jint count;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)",
                      accessibleTable);
 
     // Get the table row selection count
@@ -2561,14 +2558,14 @@
                                       getAccessibleTableRowSelectionCountMethod,
                                       accessibleTable);
         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelectionCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table row selection count = %d", count);
+        PrintDebugString("[INFO]:   ##### table row selection count = %d", count);
         return count;
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowSelectionCountMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowSelectionCountMethod == 0");
         return 0;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed");
+    PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed");
     return 0;
 }
 
@@ -2577,7 +2574,7 @@
     jthrowable exception;
     BOOL result;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)",
                      accessibleTable, row);
 
     if (isAccessibleTableRowSelectedMethod != (jmethodID) 0) {
@@ -2585,14 +2582,14 @@
                                            isAccessibleTableRowSelectedMethod,
                                            accessibleTable, row);
         EXCEPTION_CHECK("##### Getting isAccessibleTableRowSelected - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("  ##### table row isSelected = %d", result);
+        PrintDebugString("[INFO]:   ##### table row isSelected = %d", result);
         return result;
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or isAccessibleTableRowSelectedMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or isAccessibleTableRowSelectedMethod == 0");
         return FALSE;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed");
+    PrintDebugString("[ERROR]:  AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed");
     return FALSE;
 }
 
@@ -2602,7 +2599,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)",
                      accessibleTable, count, selections);
 
     if (getAccessibleTableRowSelectionsMethod == (jmethodID) 0) {
@@ -2616,10 +2613,10 @@
                                               accessibleTable,
                                               i);
         EXCEPTION_CHECK("##### Getting AccessibleTableRowSelections - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table row selection[%d] = %d", i, selections[i]);
+        PrintDebugString("[INFO]:   ##### table row selection[%d] = %d", i, selections[i]);
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded");
+    PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded");
     return TRUE;
 }
 
@@ -2630,7 +2627,7 @@
     jthrowable exception;
     jint count;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)",
                      accessibleTable);
 
     // Get the table column selection count
@@ -2639,14 +2636,14 @@
                                       getAccessibleTableColumnSelectionCountMethod,
                                       accessibleTable);
         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelectionCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table column selection count = %d", count);
+        PrintDebugString("[INFO]:   ##### table column selection count = %d", count);
         return count;
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleRowCountMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleRowCountMethod == 0");
         return 0;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed");
+    PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed");
     return 0;
 }
 
@@ -2655,7 +2652,7 @@
     jthrowable exception;
     BOOL result;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)",
                      accessibleTable, column);
 
     if (isAccessibleTableColumnSelectedMethod != (jmethodID) 0) {
@@ -2663,14 +2660,14 @@
                                            isAccessibleTableColumnSelectedMethod,
                                            accessibleTable, column);
         EXCEPTION_CHECK("##### Getting isAccessibleTableColumnSelected - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("  ##### table column isSelected = %d", result);
+        PrintDebugString("[INFO]:   ##### table column isSelected = %d", result);
         return result;
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or isAccessibleTableColumnSelectedMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or isAccessibleTableColumnSelectedMethod == 0");
         return FALSE;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed");
+    PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed");
     return FALSE;
 }
 
@@ -2679,7 +2676,7 @@
                                                                 jint *selections) {
     jthrowable exception;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)",
                      accessibleTable, count, selections);
 
     if (getAccessibleTableColumnSelectionsMethod == (jmethodID) 0) {
@@ -2693,10 +2690,10 @@
                                               accessibleTable,
                                               i);
         EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelections - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table Column selection[%d] = %d", i, selections[i]);
+        PrintDebugString("[INFO]:   ##### table Column selection[%d] = %d", i, selections[i]);
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded");
+    PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded");
     return TRUE;
 }
 
@@ -2706,7 +2703,7 @@
     jthrowable exception;
     jint result;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)",
                      accessibleTable, index);
 
     if (getAccessibleTableRowMethod != (jmethodID) 0) {
@@ -2714,14 +2711,14 @@
                                        getAccessibleTableRowMethod,
                                        accessibleTable, index);
         EXCEPTION_CHECK("##### Getting AccessibleTableRow - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table row = %d", result);
+        PrintDebugString("[INFO]:   ##### table row = %d", result);
         return result;
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableRowMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableRowMethod == 0");
         return -1;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed");
+    PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed");
     return -1;
 }
 
@@ -2730,7 +2727,7 @@
     jthrowable exception;
     jint result;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)",
                      accessibleTable, index);
 
     if (getAccessibleTableColumnMethod != (jmethodID) 0) {
@@ -2738,14 +2735,14 @@
                                        getAccessibleTableColumnMethod,
                                        accessibleTable, index);
         EXCEPTION_CHECK("##### Getting AccessibleTableColumn - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table column = %d", result);
+        PrintDebugString("[INFO]:   ##### table column = %d", result);
         return result;
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableColumnMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableColumnMethod == 0");
         return -1;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed");
+    PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed");
     return -1;
 }
 
@@ -2754,7 +2751,7 @@
     jthrowable exception;
     jint result;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)",
                      accessibleTable, row, column);
 
     if (getAccessibleTableIndexMethod != (jmethodID) 0) {
@@ -2762,14 +2759,14 @@
                                        getAccessibleTableIndexMethod,
                                        accessibleTable, row, column);
         EXCEPTION_CHECK("##### Getting getAccessibleTableIndex - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### table index = %d", result);
+        PrintDebugString("[INFO]:   ##### table index = %d", result);
         return result;
     } else {
-        PrintDebugString("  ##### Error! either env == 0 or getAccessibleTableIndexMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTableIndexMethod == 0");
         return -1;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed");
+    PrintDebugString("[ERROR]:   ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed");
     return -1;
 }
 
@@ -2786,7 +2783,7 @@
     const wchar_t *stringBytes;
     jsize length;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)",
                      accessibleContext, relationSet);
 
     if (getAccessibleRelationCountMethod == (jmethodID) 0 ||
@@ -2801,7 +2798,7 @@
                                                        getAccessibleRelationCountMethod,
                                                        accessibleContext);
     EXCEPTION_CHECK("##### Getting AccessibleRelationCount - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### AccessibleRelation count = %d", relationSet->relationCount);
+    PrintDebugString("[INFO]:   ##### AccessibleRelation count = %d", relationSet->relationCount);
 
 
     // Get the relation set
@@ -2826,11 +2823,11 @@
             // jniEnv->CallVoidMethod(accessBridgeObject,
             //                        decrementReferenceMethod, js);
             //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE);
-            PrintDebugString("##### AccessibleRelation key = %ls", relationSet->relations[i].key );
+            PrintDebugString("[INFO]: ##### AccessibleRelation key = %ls", relationSet->relations[i].key );
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleRelation key - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  AccessibleRelation key is null.");
+            PrintDebugString("[WARN]:   AccessibleRelation key is null.");
             relationSet->relations[i].key [0] = (wchar_t) 0;
         }
 
@@ -2846,11 +2843,11 @@
             jobject globalRef = jniEnv->NewGlobalRef(target);
             EXCEPTION_CHECK("Getting AccessibleRelationSet - call to NewGlobalRef()", FALSE);
             relationSet->relations[i].targets[j] = (JOBJECT64)globalRef;
-            PrintDebugString("  relation set item: %p", globalRef);
+            PrintDebugString("[INFO]:   relation set item: %p", globalRef);
         }
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded");
+    PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded");
     return TRUE;
 }
 
@@ -2868,7 +2865,7 @@
     const wchar_t *stringBytes;
     jsize length;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)",
                      accessibleContext, hypertext);
 
     // get the AccessibleHypertext
@@ -2879,10 +2876,10 @@
     jobject globalRef = jniEnv->NewGlobalRef(ht);
     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
-    PrintDebugString("  ##### AccessibleHypertext = %p", globalRef);
+    PrintDebugString("[INFO]:   ##### AccessibleHypertext = %p", globalRef);
 
     if (hypertext->accessibleHypertext == 0) {
-        PrintDebugString("  ##### null AccessibleHypertext; returning FALSE");
+        PrintDebugString("[WARN]:   ##### null AccessibleHypertext; returning FALSE");
         return false;
     }
 
@@ -2891,7 +2888,7 @@
                                                  getAccessibleHyperlinkCountMethod,accessibleContext);
 
     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### hyperlink count = %d", hypertext->linkCount);
+    PrintDebugString("[INFO]:   ##### hyperlink count = %d", hypertext->linkCount);
 
 
     // get the hypertext links
@@ -2906,7 +2903,7 @@
         jobject globalRef = jniEnv->NewGlobalRef(hl);
         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
         hypertext->links[i].accessibleHyperlink = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### AccessibleHyperlink = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
 
         // get the hyperlink text
         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
@@ -2930,11 +2927,11 @@
             // jniEnv->CallVoidMethod(accessBridgeObject,
             //                                     decrementReferenceMethod, js);
             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
-            PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[i].text );
+            PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[i].text );
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  AccessibleHyperlink text is null.");
+            PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
             hypertext->links[i].text[0] = (wchar_t) 0;
         }
 
@@ -2943,7 +2940,7 @@
                                                                hypertext->links[i].accessibleHyperlink,
                                                                i);
         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### hyperlink start index = %d", hypertext->links[i].startIndex);
+        PrintDebugString("[INFO]:   ##### hyperlink start index = %d", hypertext->links[i].startIndex);
 
 
         hypertext->links[i].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
@@ -2951,11 +2948,11 @@
                                                              hypertext->links[i].accessibleHyperlink,
                                                              i);
         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### hyperlink end index = %d", hypertext->links[i].endIndex);
+        PrintDebugString("[INFO]:   ##### hyperlink end index = %d", hypertext->links[i].endIndex);
 
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded");
+    PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded");
     return TRUE;
 }
 
@@ -2969,7 +2966,7 @@
     jthrowable exception;
     BOOL returnVal;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):",
                      accessibleContext, accessibleHyperlink);
 
     if (activateAccessibleHyperlinkMethod != (jmethodID) 0) {
@@ -2978,7 +2975,7 @@
         EXCEPTION_CHECK("activateAccessibleHyperlink - call to CallBooleanMethod()", FALSE);
         return returnVal;
     } else {
-        PrintDebugString("\r\n  Error! either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0");
+        PrintDebugString("[ERROR]: either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0");
         return FALSE;
     }
 }
@@ -2999,7 +2996,7 @@
     jthrowable exception;
     const wchar_t *stringBytes;
     jsize length;
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)",
                      accessibleContext, hypertext, nStartIndex);
 
     // get the AccessibleHypertext
@@ -3009,9 +3006,9 @@
     jobject globalRef = jniEnv->NewGlobalRef(ht);
     EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE);
     hypertext->accessibleHypertext = (JOBJECT64)globalRef;
-    PrintDebugString("  ##### AccessibleHypertext = %p", globalRef);
+    PrintDebugString("[INFO]:   ##### AccessibleHypertext = %p", globalRef);
     if (hypertext->accessibleHypertext == 0) {
-        PrintDebugString("  ##### null AccessibleHypertext; returning FALSE");
+        PrintDebugString("[WARN]:   ##### null AccessibleHypertext; returning FALSE");
         return FALSE;
     }
 
@@ -3019,7 +3016,7 @@
     hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
                                                  accessibleContext);
     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### hyperlink count = %d", hypertext->linkCount);
+    PrintDebugString("[INFO]:   ##### hyperlink count = %d", hypertext->linkCount);
 
     if (nStartIndex >= hypertext->linkCount) {
         return FALSE;
@@ -3031,7 +3028,7 @@
     // i < hypertext->linkCount
     int bufIndex = 0;
     for (int i = nStartIndex; (i < hypertext->linkCount) && (i < nStartIndex + MAX_HYPERLINKS); i++) {
-        PrintDebugString("  getting hyperlink %d ...", i);
+        PrintDebugString("[INFO]:   getting hyperlink %d ...", i);
 
         // get the hyperlink
         jobject hl = jniEnv->CallObjectMethod(accessBridgeObject,
@@ -3042,7 +3039,7 @@
         jobject globalRef = jniEnv->NewGlobalRef(hl);
         EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
         hypertext->links[bufIndex].accessibleHyperlink = (JOBJECT64)globalRef;
-        PrintDebugString("  ##### AccessibleHyperlink = %p", globalRef);
+        PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
 
         // get the hyperlink text
         jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
@@ -3067,12 +3064,12 @@
             // jniEnv->CallVoidMethod(accessBridgeObject,
             //                        decrementReferenceMethod, js);
             //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
-            PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text );
+            PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text );
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
 
         } else {
-            PrintDebugString("  AccessibleHyperlink text is null.");
+            PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
             hypertext->links[bufIndex].text[0] = (wchar_t) 0;
         }
 
@@ -3081,19 +3078,19 @@
                                                                       hypertext->links[bufIndex].accessibleHyperlink,
                                                                       i);
         EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex);
+        PrintDebugString("[INFO]:   ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex);
 
         hypertext->links[bufIndex].endIndex = jniEnv->CallIntMethod(accessBridgeObject,
                                                                     getAccessibleHyperlinkEndIndexMethod,
                                                                     hypertext->links[bufIndex].accessibleHyperlink,
                                                                     i);
         EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex);
+        PrintDebugString("[INFO]:   ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex);
 
         bufIndex++;
     }
 
-    PrintDebugString("  ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded");
+    PrintDebugString("[INFO]:   ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded");
     return TRUE;
 }
 
@@ -3101,7 +3098,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)",
                      accessibleContext);
 
     if (getAccessibleHyperlinkCountMethod == (jmethodID)0) {
@@ -3112,7 +3109,7 @@
     jint linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod,
                                            accessibleContext);
     EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", -1);
-    PrintDebugString("  ##### hyperlink count = %d", linkCount);
+    PrintDebugString("[INFO]:   ##### hyperlink count = %d", linkCount);
 
     return linkCount;
 }
@@ -3123,7 +3120,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)",
                      hypertext, nIndex);
 
     if (getAccessibleHypertextLinkIndexMethod == (jmethodID)0) {
@@ -3135,7 +3132,7 @@
                                        hypertext, nIndex);
 
     EXCEPTION_CHECK("##### Getting hyperlink index - call to CallIntMethod()", -1);
-    PrintDebugString("  ##### hyperlink index = %d", index);
+    PrintDebugString("[INFO]:   ##### hyperlink index = %d", index);
 
     return index;
 }
@@ -3148,7 +3145,7 @@
     const wchar_t *stringBytes;
     jsize length;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)",
                      hypertext, index);
 
 
@@ -3161,7 +3158,7 @@
     jobject globalRef = jniEnv->NewGlobalRef(hl);
     EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE);
     info->accessibleHyperlink = (JOBJECT64)globalRef;
-    PrintDebugString("  ##### AccessibleHyperlink = %p", globalRef);
+    PrintDebugString("[INFO]:   ##### AccessibleHyperlink = %p", globalRef);
 
     // get the hyperlink text
     jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject,
@@ -3186,12 +3183,12 @@
         // jniEnv->CallVoidMethod(accessBridgeObject,
         //                        decrementReferenceMethod, js);
         //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE);
-        PrintDebugString("##### AccessibleHyperlink text = %ls", info->text );
+        PrintDebugString("[INFO]: ##### AccessibleHyperlink text = %ls", info->text );
         jniEnv->DeleteLocalRef(js);
         EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE);
 
     } else {
-        PrintDebugString("  AccessibleHyperlink text is null.");
+        PrintDebugString("[WARN]:   AccessibleHyperlink text is null.");
         info->text[0] = (wchar_t) 0;
     }
 
@@ -3200,14 +3197,14 @@
                                              info->accessibleHyperlink,
                                              index);
     EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### hyperlink start index = %d", info->startIndex);
+    PrintDebugString("[INFO]:   ##### hyperlink start index = %d", info->startIndex);
 
     info->endIndex = jniEnv->CallIntMethod(accessBridgeObject,
                                            getAccessibleHyperlinkEndIndexMethod,
                                            info->accessibleHyperlink,
                                            index);
     EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### hyperlink end index = %d", info->endIndex);
+    PrintDebugString("[INFO]:   ##### hyperlink end index = %d", info->endIndex);
 
     return TRUE;
 }
@@ -3221,7 +3218,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)",
                      accessibleContext, keyBindings);
 
     if (getAccessibleKeyBindingsCountMethod == (jmethodID) 0 ||
@@ -3236,7 +3233,7 @@
 
     EXCEPTION_CHECK("##### Getting key bindings count - call to CallIntMethod()", FALSE);
 
-    PrintDebugString("  ##### key bindings count = %d", keyBindings->keyBindingsCount);
+    PrintDebugString("[INFO]:   ##### key bindings count = %d", keyBindings->keyBindingsCount);
 
     // get the key bindings
     for (int i = 0; i < keyBindings->keyBindingsCount && i < MAX_KEY_BINDINGS; i++) {
@@ -3247,8 +3244,9 @@
                                                                           accessibleContext,
                                                                           i);
         EXCEPTION_CHECK("##### Getting key binding character - call to CallCharMethod()", FALSE);
-        PrintDebugString("  ##### key binding character = %c", keyBindings->keyBindingInfo[i].character);
-        PrintDebugString("  ##### key binding character in hex = %hx", keyBindings->keyBindingInfo[i].character);
+        PrintDebugString("[INFO]:   ##### key binding character = %c"\
+                         "          ##### key binding character in hex = %hx"\
+                         , keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character);
 
         // get the key binding modifiers
         keyBindings->keyBindingInfo[i].modifiers = jniEnv->CallIntMethod(accessBridgeObject,
@@ -3256,7 +3254,7 @@
                                                                          accessibleContext,
                                                                          i);
         EXCEPTION_CHECK("##### Getting key binding modifiers - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers);
+        PrintDebugString("[INFO]:  ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers);
     }
     return FALSE;
 }
@@ -3269,14 +3267,14 @@
     const wchar_t *stringBytes;
     jsize length;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
                      accessibleContext, icons);
 
     if (getAccessibleIconsCountMethod == (jmethodID) 0 ||
         getAccessibleIconDescriptionMethod == (jmethodID) 0 ||
         getAccessibleIconHeightMethod == (jmethodID) 0 ||
         getAccessibleIconWidthMethod == (jmethodID) 0) {
-        PrintDebugString("  ##### missing method(s) !!!");
+        PrintDebugString("[WARN]:   ##### missing method(s) !!!");
         return FALSE;
     }
 
@@ -3286,7 +3284,7 @@
                                               getAccessibleIconsCountMethod, accessibleContext);
 
     EXCEPTION_CHECK("##### Getting icons count - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### icons count = %d", icons->iconsCount);
+    PrintDebugString("[INFO]:   ##### icons count = %d", icons->iconsCount);
 
 
     // get the icons
@@ -3314,11 +3312,11 @@
             // jniEnv->CallVoidMethod(accessBridgeObject,
             //                        decrementReferenceMethod, js);
             //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE);
-            PrintDebugString("##### AccessibleIcon description = %ls", icons->iconInfo[i].description );
+            PrintDebugString("[INFO]: ##### AccessibleIcon description = %ls", icons->iconInfo[i].description );
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleIcon description - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  AccessibleIcon description is null.");
+            PrintDebugString("[WARN]:   AccessibleIcon description is null.");
             icons->iconInfo[i].description[0] = (wchar_t) 0;
         }
 
@@ -3329,7 +3327,7 @@
                                                           accessibleContext,
                                                           i);
         EXCEPTION_CHECK("##### Getting icon height - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### icon height = %d", icons->iconInfo[i].height);
+        PrintDebugString("[INFO]:   ##### icon height = %d", icons->iconInfo[i].height);
 
         // get the icon width
         icons->iconInfo[i].width = jniEnv->CallIntMethod(accessBridgeObject,
@@ -3337,7 +3335,7 @@
                                                          accessibleContext,
                                                          i);
         EXCEPTION_CHECK("##### Getting icon width - call to CallIntMethod()", FALSE);
-        PrintDebugString("  ##### icon width = %d", icons->iconInfo[i].width);
+        PrintDebugString("[INFO]:   ##### icon width = %d", icons->iconInfo[i].width);
     }
     return FALSE;
 }
@@ -3350,12 +3348,12 @@
     const wchar_t *stringBytes;
     jsize length;
 
-    PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
+    PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)",
                      accessibleContext, actions);
 
     if (getAccessibleActionsCountMethod == (jmethodID) 0 ||
         getAccessibleActionNameMethod == (jmethodID) 0) {
-        PrintDebugString("  ##### missing method(s) !!!");
+        PrintDebugString("[WARN]:   ##### missing method(s) !!!");
         return FALSE;
     }
 
@@ -3365,7 +3363,7 @@
                                                   getAccessibleActionsCountMethod,accessibleContext);
 
     EXCEPTION_CHECK("##### Getting actions count - call to CallIntMethod()", FALSE);
-    PrintDebugString("  ##### key actions count = %d", actions->actionsCount);
+    PrintDebugString("[INFO]:   ##### key actions count = %d", actions->actionsCount);
 
 
     // get the actions
@@ -3393,11 +3391,11 @@
             // jniEnv->CallVoidMethod(accessBridgeObject,
             //                        decrementReferenceMethod, js);
             //EXCEPTION_CHECK("Getting AccessibleAction name  - call to CallVoidMethod()", FALSE);
-            PrintDebugString("##### AccessibleAction name  = %ls", actions->actionInfo[i].name  );
+            PrintDebugString("[INFO]: ##### AccessibleAction name  = %ls", actions->actionInfo[i].name  );
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleAction name  - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  AccessibleAction name  is null.");
+            PrintDebugString("[WARN]:   AccessibleAction name  is null.");
             actions->actionInfo[i].name [0] = (wchar_t) 0;
         }
     }
@@ -3411,7 +3409,7 @@
     jthrowable exception;
     BOOL returnVal;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):",
                      accessibleContext,
                      actionsToDo->actionsCount,
                      actionsToDo->actions[0].name);
@@ -3421,15 +3419,15 @@
         return FALSE;
     }
 
-    PrintDebugString("\r\n    doing %d actions ...", actionsToDo->actionsCount);
+    PrintDebugString("[INFO]:     doing %d actions ...", actionsToDo->actionsCount);
     for (int i = 0; i < actionsToDo->actionsCount && i < MAX_ACTIONS_TO_DO; i++) {
-        PrintDebugString("\r    doing action %d: %s ...", i, actionsToDo->actions[i].name);
+        PrintDebugString("[INFO]:     doing action %d: %s ...", i, actionsToDo->actions[i].name);
 
         // create a Java String for the action name
         wchar_t *actionName = (wchar_t *)actionsToDo->actions[i].name;
         jstring javaName = jniEnv->NewString(actionName, (jsize)wcslen(actionName));
         if (javaName == 0) {
-            PrintDebugString("\r    NewString failed");
+            PrintDebugString("[ERROR]:     NewString failed");
             *failure = i;
             return FALSE;
         }
@@ -3440,7 +3438,7 @@
         EXCEPTION_CHECK("doAccessibleActions - call to CallBooleanMethod()", FALSE);
 
         if (returnVal != TRUE) {
-            PrintDebugString("\r    Action %d failed", i);
+            PrintDebugString("[ERROR]:     Action %d failed", i);
             *failure = i;
             return FALSE;
         }
@@ -3464,7 +3462,7 @@
         return FALSE;
     }
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):",
                      accessibleContext, x, y);
 
     // Get the character count
@@ -3473,9 +3471,9 @@
                                                     getAccessibleCharCountFromContextMethod,
                                                     accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleCharCount - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Char count = %d", textInfo->charCount);
+        PrintDebugString("[INFO]:   Char count = %d", textInfo->charCount);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleCharCountFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleCharCountFromContextMethod == 0");
         return FALSE;
     }
 
@@ -3485,9 +3483,9 @@
                                                      getAccessibleCaretPositionFromContextMethod,
                                                      accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleCaretPosition - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Index at caret = %d", textInfo->caretIndex);
+        PrintDebugString("[INFO]:   Index at caret = %d", textInfo->caretIndex);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleCaretPositionFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleCaretPositionFromContextMethod == 0");
         return FALSE;
     }
 
@@ -3497,9 +3495,9 @@
                                                        getAccessibleIndexAtPointFromContextMethod,
                                                        accessibleContext, x, y);
         EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Index at point = %d", textInfo->indexAtPoint);
+        PrintDebugString("[INFO]:  Index at point = %d", textInfo->indexAtPoint);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -3513,7 +3511,7 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext);
 
     // Verify the Java VM still exists and AccessibleContext is
     // an instance of AccessibleText
@@ -3527,7 +3525,7 @@
                                                 getAccessibleLetterAtIndexFromContextMethod,
                                                 accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallIntMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to GetStringChars()", FALSE);
@@ -3537,15 +3535,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallVoidMethod()", FALSE);
-            PrintDebugString("  Accessible Text letter = %c", textItems->letter);
+            PrintDebugString("[INFO]:   Accessible Text letter = %c", textItems->letter);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Text letter is null.");
+            PrintDebugString("[WARN]:   Accessible Text letter is null.");
             textItems->letter = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
@@ -3556,7 +3554,7 @@
                                                 getAccessibleWordAtIndexFromContextMethod,
                                                 accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallIntMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringChars()", FALSE);
@@ -3570,15 +3568,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Text word = %ls", textItems->word);
+            wPrintDebugString(L"[INFO]:   Accessible Text word = %ls", textItems->word);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Text word is null.");
+            PrintDebugString("[WARN]:   Accessible Text word is null.");
             textItems->word[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
@@ -3588,7 +3586,7 @@
                                                 getAccessibleSentenceAtIndexFromContextMethod,
                                                 accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringChars()", FALSE);
@@ -3606,15 +3604,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Text sentence = %ls", textItems->sentence);
+            wPrintDebugString(L"[INFO]:   Accessible Text sentence = %ls", textItems->sentence);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Text sentence is null.");
+            PrintDebugString("[WARN]:   Accessible Text sentence is null.");
             textItems->sentence[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
@@ -3629,7 +3627,7 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):",
                      accessibleContext);
 
     // Verify the Java VM still exists and AccessibleContext is
@@ -3644,9 +3642,9 @@
                                                                    getAccessibleTextSelectionStartFromContextMethod,
                                                                    accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleTextSelectionStart - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Selection start = %d", selectionInfo->selectionStartIndex);
+        PrintDebugString("[INFO]:   Selection start = %d", selectionInfo->selectionStartIndex);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0");
         return FALSE;
     }
 
@@ -3656,9 +3654,9 @@
                                                                  getAccessibleTextSelectionEndFromContextMethod,
                                                                  accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleTextSelectionEnd - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Selection end = %d", selectionInfo->selectionEndIndex);
+        PrintDebugString("[INFO]:   Selection end = %d", selectionInfo->selectionEndIndex);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0");
         return FALSE;
     }
 
@@ -3668,7 +3666,7 @@
                                                 getAccessibleTextSelectedTextFromContextMethod,
                                                 accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringChars()", FALSE);
@@ -3682,15 +3680,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE);
-            PrintDebugString("  Accessible's selected text = %s", selectionInfo->selectedText);
+            PrintDebugString("[INFO]:   Accessible's selected text = %s", selectionInfo->selectedText);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible's selected text is null.");
+            PrintDebugString("[WARN]:   Accessible's selected text is null.");
             selectionInfo->selectedText[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0");
+        PrintDebugString("[WARN]: either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -3704,7 +3702,7 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext);
 
     // Verify the Java VM still exists and AccessibleContext is
     // an instance of AccessibleText
@@ -3713,7 +3711,7 @@
     }
 
     if (accessibleContext == (jobject) 0) {
-        PrintDebugString(" passed in AccessibleContext == null! (oops)");
+        PrintDebugString("[WARN]:  passed in AccessibleContext == null! (oops)");
 
         attributes->bold = FALSE;
         attributes->italic = FALSE;
@@ -3740,19 +3738,19 @@
 
     // Get the AttributeSet
     if (getAccessibleAttributeSetAtIndexFromContextMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting AttributeSet at index...");
+        PrintDebugString("[INFO]:  Getting AttributeSet at index...");
         AttributeSet = jniEnv->CallObjectMethod(accessBridgeObject,
                                                 getAccessibleAttributeSetAtIndexFromContextMethod,
                                                 accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to CallObjectMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
     // It is legal for the AttributeSet object to be null, in which case we return false!
     if (AttributeSet == (jobject) 0) {
-        PrintDebugString(" AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3");
+        PrintDebugString("[WARN]:  AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3");
 
         attributes->bold = FALSE;
         attributes->italic = FALSE;
@@ -3779,13 +3777,13 @@
 
     // Get the bold setting
     if (getBoldFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting bold from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting bold from AttributeSet...");
         attributes->bold = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
                                                             getBoldFromAttributeSetMethod,
                                                             AttributeSet);
         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallBooleanMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getBoldFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getBoldFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3796,13 +3794,13 @@
 
     // Get the italic setting
     if (getItalicFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting italic from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting italic from AttributeSet...");
         attributes->italic = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
                                                               getItalicFromAttributeSetMethod,
                                                               AttributeSet);
         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallBooleanMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getItalicdFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getItalicdFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3813,13 +3811,13 @@
 
     // Get the underline setting
     if (getUnderlineFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting underline from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting underline from AttributeSet...");
         attributes->underline = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
                                                                  getUnderlineFromAttributeSetMethod,
                                                                  AttributeSet);
         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallBooleanMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getUnderlineFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getUnderlineFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3830,13 +3828,13 @@
 
     // Get the strikethrough setting
     if (getStrikethroughFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting strikethrough from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting strikethrough from AttributeSet...");
         attributes->strikethrough = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
                                                                      getStrikethroughFromAttributeSetMethod,
                                                                      AttributeSet);
         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallBooleanMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getStrikethroughFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getStrikethroughFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3847,13 +3845,13 @@
 
     // Get the superscript setting
     if (getSuperscriptFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting superscript from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting superscript from AttributeSet...");
         attributes->superscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
                                                                    getSuperscriptFromAttributeSetMethod,
                                                                    AttributeSet);
         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getSuperscripteFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getSuperscripteFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3864,13 +3862,13 @@
 
     // Get the subscript setting
     if (getSubscriptFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting subscript from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting subscript from AttributeSet...");
         attributes->subscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject,
                                                                  getSubscriptFromAttributeSetMethod,
                                                                  AttributeSet);
         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallBooleanMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getSubscriptFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getSubscriptFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3881,7 +3879,7 @@
 
     // Get the backgroundColor setting
     if (getBackgroundColorFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting backgroundColor from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting backgroundColor from AttributeSet...");
         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
                                                 getBackgroundColorFromAttributeSetMethod,
                                                 AttributeSet);
@@ -3899,15 +3897,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  AttributeSet's background color = %ls", attributes->backgroundColor);
+            wPrintDebugString(L"[INFO]:   AttributeSet's background color = %ls", attributes->backgroundColor);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  AttributeSet's background color is null.");
+            PrintDebugString("[WARN]:   AttributeSet's background color is null.");
             attributes->backgroundColor[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getBackgroundColorFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getBackgroundColorFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3918,7 +3916,7 @@
 
     // Get the foregroundColor setting
     if (getForegroundColorFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting foregroundColor from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting foregroundColor from AttributeSet...");
         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
                                                 getForegroundColorFromAttributeSetMethod,
                                                 AttributeSet);
@@ -3936,15 +3934,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  AttributeSet's foreground color = %ls", attributes->foregroundColor);
+            wPrintDebugString(L"[INFO]:   AttributeSet's foreground color = %ls", attributes->foregroundColor);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  AttributeSet's foreground color is null.");
+            PrintDebugString("[WARN]:   AttributeSet's foreground color is null.");
             attributes->foregroundColor[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getForegroundColorFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getForegroundColorFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3955,7 +3953,7 @@
 
     // Get the fontFamily setting
     if (getFontFamilyFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting fontFamily from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting fontFamily from AttributeSet...");
         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
                                                 getFontFamilyFromAttributeSetMethod,
                                                 AttributeSet);
@@ -3973,15 +3971,15 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  AttributeSet's fontFamily = %ls", attributes->fontFamily);
+            wPrintDebugString(L"[INFO]:   AttributeSet's fontFamily = %ls", attributes->fontFamily);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  AttributeSet's fontFamily is null.");
+            PrintDebugString("[WARN]:   AttributeSet's fontFamily is null.");
             attributes->backgroundColor[0] = (wchar_t) 0;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getFontFamilyFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getFontFamilyFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -3992,14 +3990,14 @@
 
     // Get the font size
     if (getFontSizeFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting font size from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting font size from AttributeSet...");
         attributes->fontSize = jniEnv->CallIntMethod(accessBridgeObject,
                                                      getFontSizeFromAttributeSetMethod,
                                                      AttributeSet);
         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallIntMethod()", FALSE);
-        PrintDebugString("  AttributeSet's font size = %d", attributes->fontSize);
+        PrintDebugString("[INFO]:   AttributeSet's font size = %d", attributes->fontSize);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4011,13 +4009,13 @@
 
     // Get the alignment setting
     if (getAlignmentFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting alignment from AttributeSet...");
+        PrintDebugString("[INFO]: Getting alignment from AttributeSet...");
         attributes->alignment = jniEnv->CallIntMethod(accessBridgeObject,
                                                       getAlignmentFromAttributeSetMethod,
                                                       AttributeSet);
         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAlignmentFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4028,13 +4026,13 @@
 
     // Get the bidiLevel setting
     if (getBidiLevelFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting bidiLevel from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting bidiLevel from AttributeSet...");
         attributes->bidiLevel = jniEnv->CallIntMethod(accessBridgeObject,
                                                       getBidiLevelFromAttributeSetMethod,
                                                       AttributeSet);
         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getBidiLevelFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getBidiLevelFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4045,13 +4043,13 @@
 
     // Get the firstLineIndent setting
     if (getFirstLineIndentFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting firstLineIndent from AttributeSet...");
+        PrintDebugString("[ERROR]:  Getting firstLineIndent from AttributeSet...");
         attributes->firstLineIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
                                                                        getFirstLineIndentFromAttributeSetMethod,
                                                                        AttributeSet);
         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4062,13 +4060,13 @@
 
     // Get the leftIndent setting
     if (getLeftIndentFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting leftIndent from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting leftIndent from AttributeSet...");
         attributes->leftIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
                                                                   getLeftIndentFromAttributeSetMethod,
                                                                   AttributeSet);
         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getLeftIndentFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getLeftIndentFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4079,13 +4077,13 @@
 
     // Get the rightIndent setting
     if (getRightIndentFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting rightIndent from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting rightIndent from AttributeSet...");
         attributes->rightIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
                                                                    getRightIndentFromAttributeSetMethod,
                                                                    AttributeSet);
         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getRightIndentFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getRightIndentFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4096,13 +4094,13 @@
 
     // Get the lineSpacing setting
     if (getLineSpacingFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting lineSpacing from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting lineSpacing from AttributeSet...");
         attributes->lineSpacing = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
                                                                    getLineSpacingFromAttributeSetMethod,
                                                                    AttributeSet);
         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getLineSpacingFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getLineSpacingFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4113,13 +4111,13 @@
 
     // Get the spaceAbove setting
     if (getSpaceAboveFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting spaceAbove from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting spaceAbove from AttributeSet...");
         attributes->spaceAbove = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
                                                                   getSpaceAboveFromAttributeSetMethod,
                                                                   AttributeSet);
         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getSpaceAboveFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getSpaceAboveFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4130,13 +4128,13 @@
 
     // Get the spaceBelow setting
     if (getSpaceBelowFromAttributeSetMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting spaceBelow from AttributeSet...");
+        PrintDebugString("[INFO]:  Getting spaceBelow from AttributeSet...");
         attributes->spaceBelow = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject,
                                                                   getSpaceBelowFromAttributeSetMethod,
                                                                   AttributeSet);
         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallIntMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or getSpaceBelowFromAttributeSetMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getSpaceBelowFromAttributeSetMethod == 0");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallVoidMethod()", FALSE);
@@ -4147,12 +4145,12 @@
 
     // Release the AttributeSet object
     if (decrementReferenceMethod != (jmethodID) 0) {
-        PrintDebugString(" Decrementing reference to AttributeSet...");
+        PrintDebugString("[INFO]:  Decrementing reference to AttributeSet...");
         jniEnv->CallVoidMethod(accessBridgeObject,
                                decrementReferenceMethod, AttributeSet);
         EXCEPTION_CHECK("Releasing AttributeSet object - call to CallVoidMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or accessBridgeObject == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or accessBridgeObject == 0");
         jniEnv->DeleteLocalRef(AttributeSet);
         EXCEPTION_CHECK("Releasing AttributeSet object - call to DeleteLocalRef()", FALSE);
         return FALSE;
@@ -4160,12 +4158,12 @@
 
     // Get the full attributes string at index
     if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) {
-        PrintDebugString(" Getting full attributes string from Context...");
+        PrintDebugString("[INFO]:  Getting full attributes string from Context...");
         js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject,
                                                 getAccessibleAttributesAtIndexFromContextMethod,
                                                 accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:  returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE);
@@ -4179,18 +4177,18 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Text attributes = %ls", attributes->fullAttributesString);
+            wPrintDebugString(L"[INFO]:   Accessible Text attributes = %ls", attributes->fullAttributesString);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  Accessible Text attributes is null.");
+            PrintDebugString("[WARN]:   Accessible Text attributes is null.");
             attributes->fullAttributesString[0] = (wchar_t) 0;
             jniEnv->DeleteLocalRef(AttributeSet);
             EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE);
             return FALSE;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0");
         jniEnv->DeleteLocalRef(AttributeSet);
         return FALSE;
     }
@@ -4205,7 +4203,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d",
                      accessibleContext, index);
 
     // Verify the Java VM still exists and AccessibleContext is
@@ -4220,9 +4218,9 @@
                                             getAccessibleXcoordTextRectAtIndexFromContextMethod,
                                             accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleXcoordTextRect - call to CallIntMethod()", FALSE);
-        PrintDebugString("  X coord = %d", rectInfo->x);
+        PrintDebugString("[INFO]:  X coord = %d", rectInfo->x);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
@@ -4232,9 +4230,9 @@
                                             getAccessibleYcoordTextRectAtIndexFromContextMethod,
                                             accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleYcoordTextRect - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Y coord = %d", rectInfo->y);
+        PrintDebugString("[INFO]:   Y coord = %d", rectInfo->y);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0");
+        PrintDebugString("[INFO]:  either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
@@ -4244,9 +4242,9 @@
                                                 getAccessibleWidthTextRectAtIndexFromContextMethod,
                                                 accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleWidthTextRect - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Width = %d", rectInfo->width);
+        PrintDebugString("[INFO]: Width = %d", rectInfo->width);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0");
+        PrintDebugString("[INFO]: either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
@@ -4256,9 +4254,9 @@
                                                  getAccessibleHeightTextRectAtIndexFromContextMethod,
                                                  accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleHeightTextRect - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Height = %d", rectInfo->height);
+        PrintDebugString("[INFO]: Height = %d", rectInfo->height);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0");
         return FALSE;
     }
 
@@ -4275,7 +4273,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d",
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d",
                      accessibleContext, index);
 
     // Verify the Java VM still exists and AccessibleContext is
@@ -4290,9 +4288,9 @@
                                             getCaretLocationXMethod,
                                             accessibleContext, index);
         EXCEPTION_CHECK("Getting caret X coordinate - call to CallIntMethod()", FALSE);
-        PrintDebugString("  X coord = %d", rectInfo->x);
+        PrintDebugString("[INFO]:   X coord = %d", rectInfo->x);
     } else {
-        PrintDebugString("  Error! either env == 0 or getCaretLocationXMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationXMethod == 0");
         return FALSE;
     }
 
@@ -4302,9 +4300,9 @@
                                             getCaretLocationYMethod,
                                             accessibleContext, index);
         EXCEPTION_CHECK("Getting caret Y coordinate - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Y coord = %d", rectInfo->y);
+        PrintDebugString("[INFO]:   Y coord = %d", rectInfo->y);
     } else {
-        PrintDebugString("  Error! either env == 0 or getCaretLocationYMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationYMethod == 0");
         return FALSE;
     }
 
@@ -4314,9 +4312,9 @@
                                                 getCaretLocationWidthMethod,
                                                 accessibleContext, index);
         EXCEPTION_CHECK("Getting caret width - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Width = %d", rectInfo->width);
+        PrintDebugString("[INFO]:   Width = %d", rectInfo->width);
     } else {
-        PrintDebugString("  Error! either env == 0 or getCaretLocationWidthMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationWidthMethod == 0");
         return FALSE;
     }
 
@@ -4326,9 +4324,9 @@
                                                  getCaretLocationHeightMethod,
                                                  accessibleContext, index);
         EXCEPTION_CHECK("Getting caret height - call to CallIntMethod()", FALSE);
-        PrintDebugString("  Height = %d", rectInfo->height);
+        PrintDebugString("[INFO]:   Height = %d", rectInfo->height);
     } else {
-        PrintDebugString("  Error! either env == 0 or getCaretLocationHeightMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getCaretLocationHeightMethod == 0");
         return FALSE;
     }
 
@@ -4342,7 +4340,7 @@
 
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext);
 
     // Verify the Java VM still exists and AccessibleContext is
     // an instance of AccessibleText
@@ -4356,9 +4354,9 @@
                                             getAccessibleTextLineLeftBoundsFromContextMethod,
                                             accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleTextLineLeftBounds - call to CallIntMethod()", FALSE);
-        PrintDebugString("  startIndex = %d", *startIndex);
+        PrintDebugString("[INFO]:   startIndex = %d", *startIndex);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0");
         return FALSE;
     }
 
@@ -4368,9 +4366,9 @@
                                           getAccessibleTextLineRightBoundsFromContextMethod,
                                           accessibleContext, index);
         EXCEPTION_CHECK("Getting AccessibleTextLineRightBounds - call to CallIntMethod()", FALSE);
-        PrintDebugString("  endIndex = %d", *endIndex);
+        PrintDebugString("[INFO]:   endIndex = %d", *endIndex);
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0");
         return FALSE;
     }
 
@@ -4385,7 +4383,7 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len);
 
     // Verify the Java VM still exists and AccessibleContext is
     // an instance of AccessibleText
@@ -4395,7 +4393,7 @@
 
     // range is inclusive
     if (end < start) {
-        PrintDebugString("  Error! end < start!");
+        PrintDebugString("[ERROR]:  end < start!");
         text[0] = (wchar_t) 0;
         return FALSE;
     }
@@ -4406,32 +4404,32 @@
                                                 getAccessibleTextRangeFromContextMethod,
                                                 accessibleContext, start, end);
         EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringChars()", FALSE);
-            wPrintDebugString(L"  Accessible Text stringBytes returned from Java = %ls", stringBytes);
+            wPrintDebugString(L"[INFO]:   Accessible Text stringBytes returned from Java = %ls", stringBytes);
             wcsncpy(text, stringBytes, len);
             length = jniEnv->GetStringLength(js);
-            PrintDebugString("  Accessible Text stringBytes length = %d", length);
+            PrintDebugString("[INFO]:  Accessible Text stringBytes length = %d", length);
             text[length < len ? length : len - 2] = (wchar_t) 0;
-            wPrintDebugString(L"  Accessible Text 'text' after null termination = %ls", text);
+            wPrintDebugString(L"[INFO]:   Accessible Text 'text' after null termination = %ls", text);
             EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE);
             jniEnv->ReleaseStringChars(js, stringBytes);
             EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE);
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE);
-            wPrintDebugString(L"  Accessible Text range = %ls", text);
+            wPrintDebugString(L"[INFO]:   Accessible Text range = %ls", text);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting AccessibleTextRange - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  current Accessible Text range is null.");
+            PrintDebugString("[WARN]:   current Accessible Text range is null.");
             text[0] = (wchar_t) 0;
             return FALSE;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleTextRangeFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleTextRangeFromContextMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -4446,7 +4444,7 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext);
 
     // Get the current Accessible Value
     if (getCurrentAccessibleValueFromContextMethod != (jmethodID) 0) {
@@ -4454,7 +4452,7 @@
                                                 getCurrentAccessibleValueFromContextMethod,
                                                 accessibleContext);
         EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringChars()", FALSE);
@@ -4467,16 +4465,16 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE);
-            PrintDebugString("  current Accessible Value = %s", value);
+            PrintDebugString("[INFO]:   current Accessible Value = %s", value);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  current Accessible Value is null.");
+            PrintDebugString("[WARN]:   current Accessible Value is null.");
             value[0] = (wchar_t) 0;
             return FALSE;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getCurrentAccessibleValueFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or getCurrentAccessibleValueFromContextMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -4489,7 +4487,7 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext);
 
     // Get the maximum Accessible Value
     if (getMaximumAccessibleValueFromContextMethod != (jmethodID) 0) {
@@ -4497,7 +4495,7 @@
                                                 getMaximumAccessibleValueFromContextMethod,
                                                 accessibleContext);
         EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringChars()", FALSE);
@@ -4510,16 +4508,16 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE);
-            PrintDebugString("  maximum Accessible Value = %s", value);
+            PrintDebugString("[INFO]:   maximum Accessible Value = %s", value);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  maximum Accessible Value is null.");
+            PrintDebugString("[WARN]:   maximum Accessible Value is null.");
             value[0] = (wchar_t) 0;
             return FALSE;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getMaximumAccessibleValueFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getMaximumAccessibleValueFromContextMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -4532,7 +4530,7 @@
     jthrowable exception;
     jsize length;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext);
 
     // Get the mimimum Accessible Value
     if (getMinimumAccessibleValueFromContextMethod != (jmethodID) 0) {
@@ -4540,7 +4538,7 @@
                                                 getMinimumAccessibleValueFromContextMethod,
                                                 accessibleContext);
         EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallObjectMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod(), js = %p", js);
+        PrintDebugString("[INFO]:   returned from CallObjectMethod(), js = %p", js);
         if (js != (jstring) 0) {
             stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0);
             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringChars()", FALSE);
@@ -4553,16 +4551,16 @@
             jniEnv->CallVoidMethod(accessBridgeObject,
                                    decrementReferenceMethod, js);
             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE);
-            PrintDebugString("  mimimum Accessible Value = %s", value);
+            PrintDebugString("[INFO]:   mimimum Accessible Value = %s", value);
             jniEnv->DeleteLocalRef(js);
             EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to DeleteLocalRef()", FALSE);
         } else {
-            PrintDebugString("  mimimum Accessible Value is null.");
+            PrintDebugString("[WARN]:   mimimum Accessible Value is null.");
             value[0] = (wchar_t) 0;
             return FALSE;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or getMinimumAccessibleValueFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getMinimumAccessibleValueFromContextMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -4575,7 +4573,7 @@
 AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) {
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext);
 
     // Add the child to the AccessibleSelection
     if (addAccessibleSelectionFromContextMethod != (jmethodID) 0) {
@@ -4583,9 +4581,9 @@
                                addAccessibleSelectionFromContextMethod,
                                accessibleContext, i);
         EXCEPTION_CHECK_VOID("Doing addAccessibleSelection - call to CallVoidMethod()");
-        PrintDebugString("  returned from CallObjectMethod()");
+        PrintDebugString("[INFO]:   returned from CallObjectMethod()");
     } else {
-        PrintDebugString("  Error! either env == 0 or addAccessibleSelectionFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or addAccessibleSelectionFromContextMethod == 0");
     }
 }
 
@@ -4593,7 +4591,7 @@
 AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) {
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext);
 
     // Clearing the Selection of the AccessibleSelection
     if (clearAccessibleSelectionFromContextMethod != (jmethodID) 0) {
@@ -4601,9 +4599,9 @@
                                clearAccessibleSelectionFromContextMethod,
                                accessibleContext);
         EXCEPTION_CHECK_VOID("Doing clearAccessibleSelection - call to CallVoidMethod()");
-        PrintDebugString("  returned from CallObjectMethod()");
+        PrintDebugString("[INFO]:   returned from CallObjectMethod()");
     } else {
-        PrintDebugString("  Error! either env == 0 or clearAccessibleSelectionFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or clearAccessibleSelectionFromContextMethod == 0");
     }
 }
 
@@ -4613,7 +4611,7 @@
     jobject globalRef;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext);
 
     if (getAccessibleSelectionContextFromContextMethod != (jmethodID) 0) {
         returnedAccessibleContext = jniEnv->CallObjectMethod(
@@ -4625,11 +4623,11 @@
         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to NewGlobalRef()", (jobject) 0);
         jniEnv->DeleteLocalRef(returnedAccessibleContext);
         EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to DeleteLocalRef()", (jobject) 0);
-        PrintDebugString("  Returning - returnedAccessibleContext = %p; globalRef = %p",
+        PrintDebugString("[INFO]:   Returning - returnedAccessibleContext = %p; globalRef = %p",
                          returnedAccessibleContext, globalRef);
         return globalRef;
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleSelectionContextFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionContextFromContextMethod == 0");
         return (jobject) 0;
     }
 }
@@ -4639,7 +4637,7 @@
     int count;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext);
 
     // Get (& return) the # of items selected in the AccessibleSelection
     if (getAccessibleSelectionCountFromContextMethod != (jmethodID) 0) {
@@ -4647,10 +4645,10 @@
                                       getAccessibleSelectionCountFromContextMethod,
                                       accessibleContext);
         EXCEPTION_CHECK("Getting AccessibleSelectionCount - call to CallIntMethod()", -1);
-        PrintDebugString("  returned from CallObjectMethod()");
+        PrintDebugString("[INFO]:   returned from CallObjectMethod()");
         return count;
     } else {
-        PrintDebugString("  Error! either env == 0 or getAccessibleSelectionCountFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or getAccessibleSelectionCountFromContextMethod == 0");
         return -1;
     }
 }
@@ -4660,7 +4658,7 @@
     jboolean result;
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext);
 
     // Get (& return) the # of items selected in the AccessibleSelection
     if (isAccessibleChildSelectedFromContextMethod != (jmethodID) 0) {
@@ -4668,12 +4666,12 @@
                                            isAccessibleChildSelectedFromContextMethod,
                                            accessibleContext, i);
         EXCEPTION_CHECK("Doing isAccessibleChildSelected - call to CallBooleanMethod()", FALSE);
-        PrintDebugString("  returned from CallObjectMethod()");
+        PrintDebugString("[INFO]:   returned from CallObjectMethod()");
         if (result != 0) {
             return TRUE;
         }
     } else {
-        PrintDebugString("  Error! either env == 0 or isAccessibleChildSelectedFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or isAccessibleChildSelectedFromContextMethod == 0");
     }
     return FALSE;
 }
@@ -4683,7 +4681,7 @@
 AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) {
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext);
 
     // Remove the i-th child from the AccessibleSelection
     if (removeAccessibleSelectionFromContextMethod != (jmethodID) 0) {
@@ -4691,9 +4689,9 @@
                                removeAccessibleSelectionFromContextMethod,
                                accessibleContext, i);
         EXCEPTION_CHECK_VOID("Doing removeAccessibleSelection - call to CallVoidMethod()");
-        PrintDebugString("  returned from CallObjectMethod()");
+        PrintDebugString("[INFO]:   returned from CallObjectMethod()");
     } else {
-        PrintDebugString("  Error! either env == 0 or removeAccessibleSelectionFromContextMethod == 0");
+        PrintDebugString("[ERROR]:  either env == 0 or removeAccessibleSelectionFromContextMethod == 0");
     }
 }
 
@@ -4701,7 +4699,7 @@
 AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) {
     jthrowable exception;
 
-    PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext);
+    PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext);
 
     // Select all children (if possible) of the AccessibleSelection
     if (selectAllAccessibleSelectionFromContextMethod != (jmethodID) 0) {
@@ -4709,9 +4707,9 @@
                                selectAllAccessibleSelectionFromContextMethod,
                                accessibleContext);
         EXCEPTION_CHECK_VOID("Doing selectAllAccessibleSelection - call to CallVoidMethod()");
-        PrintDebugString("  returned from CallObjectMethod()");
+        PrintDebugString("[INFO]:   returned from CallObjectMethod()");
     } else {
-        PrintDebugString("  Error! either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0");
     }
 }
 
@@ -4722,7 +4720,7 @@
 AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) {
     jthrowable exception;
 
-    PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type);
+    PrintDebugString("[INFO]:   in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type);
 
     // Let AccessBridge know we want to add an event type
     if (addJavaEventNotificationMethod != (jmethodID) 0) {
@@ -4730,7 +4728,7 @@
                                addJavaEventNotificationMethod, type);
         EXCEPTION_CHECK("Doing addJavaEventNotification - call to CallVoidMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or addJavaEventNotificationMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or addJavaEventNotificationMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -4740,7 +4738,7 @@
 AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) {
     jthrowable exception;
 
-    PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type);
+    PrintDebugString("[INFO]:  in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type);
 
     // Let AccessBridge know we want to remove an event type
     if (removeJavaEventNotificationMethod != (jmethodID) 0) {
@@ -4748,7 +4746,7 @@
                                removeJavaEventNotificationMethod, type);
         EXCEPTION_CHECK("Doing removeJavaEventNotification - call to CallVoidMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or removeJavaEventNotificationMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or removeJavaEventNotificationMethod == 0");
         return FALSE;
     }
     return TRUE;
@@ -4758,19 +4756,19 @@
 AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) {
     jthrowable exception;
 
-    PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type);
+    PrintDebugString("[INFO]:   in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type);
 
     // Let AccessBridge know we want to add an event type
     if (addAccessibilityEventNotificationMethod != (jmethodID) 0) {
-        PrintDebugString("\r\n     addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject);
+        PrintDebugString("[INFO]:    addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject);
         jniEnv->CallVoidMethod(accessBridgeObject,
                                addAccessibilityEventNotificationMethod, type);
         EXCEPTION_CHECK("Doing addAccessibilityEvent - call to CallVoidMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or addAccessibilityEventNotificationMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or addAccessibilityEventNotificationMethod == 0");
         return FALSE;
     }
-    PrintDebugString("\r\n     addAccessibilityEventNotification: just returning true");
+    PrintDebugString("[INFO]:     addAccessibilityEventNotification: just returning true");
     return TRUE;
 }
 
@@ -4778,7 +4776,7 @@
 AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) {
     jthrowable exception;
 
-    PrintDebugString("\r\n  in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type);
+    PrintDebugString("[INFO]:  in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type);
 
     // Let AccessBridge know we want to remove an event type
     if (removeAccessibilityEventNotificationMethod != (jmethodID) 0) {
@@ -4786,7 +4784,7 @@
                                removeAccessibilityEventNotificationMethod, type);
         EXCEPTION_CHECK("Doing removeAccessibilityEvent - call to CallVoidMethod()", FALSE);
     } else {
-        PrintDebugString("  Error! either env == 0 or removeAccessibilityEventNotificationMethod == 0");
+        PrintDebugString("[ERROR]: either env == 0 or removeAccessibilityEventNotificationMethod == 0");
         return FALSE;
     }
     return TRUE;
diff --git a/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp b/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp
index 2647db6..3d66374 100644
--- a/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp
+++ b/src/windows/native/sun/bridge/AccessBridgeJavaVMInstance.cpp
@@ -188,7 +188,7 @@
  *               with the Java AccessBridge DLL
  *
  *               NOTE: WM_COPYDATA is only for one-way IPC; there
- *               is now way to return parameters (especially big ones)
+ *               is no way to return parameters (especially big ones)
  *               Use sendMemoryPackage() to do that!
  */
 LRESULT
@@ -198,8 +198,8 @@
     toCopy.cbData = bufsize;
     toCopy.lpData = buffer;
 
-    PrintDebugString("In AccessBridgeVMInstance::sendPackage");
-    PrintDebugString("    javaAccessBridgeWindow: %p", javaAccessBridgeWindow);
+    PrintDebugString("[INFO]: In AccessBridgeVMInstance::sendPackage");
+    PrintDebugString("[INFO]:     javaAccessBridgeWindow: %p", javaAccessBridgeWindow);
     /* This was SendMessage.  Normally that is a blocking call.  However, if
      * SendMessage is sent to another process, e.g. another JVM and an incoming
      * SendMessage is pending, control will be passed to the DialogProc to handle
@@ -280,7 +280,7 @@
             char *done = &memoryMappedView[bufsize];
             *done = 0;
 
-            PrintDebugString("    javaAccessBridgeWindow: %p", javaAccessBridgeWindow);
+            PrintDebugString("[INFO]:     javaAccessBridgeWindow: %p", javaAccessBridgeWindow);
             // See the comment above the call to SendMessageTimeout in SendPackage method above.
             UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG;
             DWORD_PTR out; // not used
@@ -309,7 +309,7 @@
  */
 HWND
 AccessBridgeJavaVMInstance::findAccessBridgeWindow(long javaVMID) {
-    PrintDebugString("In findAccessBridgeWindow");
+    PrintDebugString("[INFO]: In findAccessBridgeWindow");
     // no need to recurse really
     if (vmID == javaVMID) {
         return javaAccessBridgeWindow;
@@ -338,7 +338,7 @@
  */
 AccessBridgeJavaVMInstance *
 AccessBridgeJavaVMInstance::findABJavaVMInstanceFromJavaHWND(HWND window) {
-    PrintDebugString("In findABJavaInstanceFromJavaHWND");
+    PrintDebugString("[INFO]: In findABJavaInstanceFromJavaHWND");
     // no need to recurse really
     if (javaAccessBridgeWindow == window) {
         return this;
diff --git a/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp b/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp
index 562fdce..e951a62 100644
--- a/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp
+++ b/src/windows/native/sun/bridge/AccessBridgeMessageQueue.cpp
@@ -88,17 +88,17 @@
  */
 QueueReturns
 AccessBridgeMessageQueue::add(AccessBridgeQueueElement *element) {
-    PrintDebugString("  in AccessBridgeMessageQueue::add()");
-    PrintDebugString("    queue size = %d", size);
+    PrintDebugString("[INFO]:   in AccessBridgeMessageQueue::add()");
+    PrintDebugString("[INFO]:     queue size = %d", size);
 
     QueueReturns returnVal = cElementPushedOK;
     if (queueLocked) {
-        PrintDebugString("    queue was locked; returning cQueueInUse!");
+        PrintDebugString("[WARN]:     queue was locked; returning cQueueInUse!");
         return cQueueInUse;
     }
     queueLocked = TRUE;
     {
-        PrintDebugString("    adding element to queue!");
+        PrintDebugString("[INFO]:     adding element to queue!");
         if (end == (AccessBridgeQueueElement *) 0) {
             if (start == (AccessBridgeQueueElement *) 0 && size == 0) {
                 start = element;
@@ -118,7 +118,7 @@
         }
     }
     queueLocked = FALSE;
-    PrintDebugString("    returning from AccessBridgeMessageQueue::add()");
+    PrintDebugString("[INFO]:     returning from AccessBridgeMessageQueue::add()");
     return returnVal;
 }
 
@@ -129,17 +129,17 @@
  */
 QueueReturns
 AccessBridgeMessageQueue::remove(AccessBridgeQueueElement **element) {
-    PrintDebugString("  in AccessBridgeMessageQueue::remove()");
-    PrintDebugString("    queue size = %d", size);
+    PrintDebugString("[INFO]:   in AccessBridgeMessageQueue::remove()");
+    PrintDebugString("[INFO]:     queue size = %d", size);
 
     QueueReturns returnVal = cMoreMessages;
     if (queueLocked) {
-        PrintDebugString("    queue was locked; returning cQueueInUse!");
+        PrintDebugString("[WARN]:     queue was locked; returning cQueueInUse!");
         return cQueueInUse;
     }
     queueLocked = TRUE;
     {
-        PrintDebugString("    removing element from queue!");
+        PrintDebugString("[INFO]:     removing element from queue!");
         if (size > 0) {
             if (start != (AccessBridgeQueueElement *) 0) {
                 *element = start;
@@ -161,7 +161,7 @@
         }
     }
     queueLocked = FALSE;
-    PrintDebugString("    returning from AccessBridgeMessageQueue::remove()");
+    PrintDebugString("[INFO]:     returning from AccessBridgeMessageQueue::remove()");
     return returnVal;
 }
 
diff --git a/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp b/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp
index 2472bc7..643c9ac 100644
--- a/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp
+++ b/src/windows/native/sun/bridge/AccessBridgeWindowsEntryPoints.cpp
@@ -51,7 +51,6 @@
         // open our window
         if (theWindowsAccessBridge != (WinAccessBridge *) 0) {
             theWindowsAccessBridge->initWindow();
-            DEBUG_CODE(SetDlgItemText(theDialogWindow, cInvokedByText, "Windows"));
         }
     }
 
diff --git a/src/windows/native/sun/bridge/JavaAccessBridge.cpp b/src/windows/native/sun/bridge/JavaAccessBridge.cpp
index 3feb019..a688301 100644
--- a/src/windows/native/sun/bridge/JavaAccessBridge.cpp
+++ b/src/windows/native/sun/bridge/JavaAccessBridge.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -87,57 +87,35 @@
      */
     JNIEXPORT void JNICALL
     Java_com_sun_java_accessibility_AccessBridge_runDLL(JNIEnv *env, jobject obj) {
-        PrintDebugString("\r\nJavaAccessBridge.DLL runDLL() called");
+        PrintDebugString("[INFO]: JavaAccessBridge.DLL runDLL() called");
         theJavaAccessBridge->javaRun(env, obj);
     }
 
-#if 0 // SetDlgItemText has caused problems with JAWS
-    /**
-     * Append debug info to dialog
-     *
-     */
-    void AppendToCallInfo(char *s) {
-        char buffer[4096];
-
-        PrintDebugString(s);
-
-        GetDlgItemText(theDialogWindow, cCallInfo, buffer, sizeof(buffer));
-        if (strlen(buffer) < (sizeof(buffer) - strlen(s))) {
-            strncat(buffer, s, sizeof(buffer));
-            SetDlgItemText(theDialogWindow, cCallInfo, buffer);
-        } else {
-            SetDlgItemText(theDialogWindow, cCallInfo, s);
-        }
-    }
-#endif
-
-
     /**
      * Our window proc
      *
      */
-    BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) {
+    BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
         int command;
         COPYDATASTRUCT *sentToUs;
         char *package;
-        //DEBUG_CODE(char buffer[256]);
 
         switch (message) {
         case WM_INITDIALOG:
-            //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Initializing"));
+            PrintDebugString("[INFO]: In AccessBridgeDialog - Initializing");
             break;
 
         case WM_COMMAND:
             command = LOWORD (wParam);
+            PrintDebugString("[INFO]: In AccessBridgeDialog - Got WM_COMMAND, command: %X", command);
             break;
 
             // call from Java with data for us to deliver
         case WM_COPYDATA:
             if (theDialogWindow == (HWND) wParam) {
-                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got WM_COPYDATA from ourselves"));
+                PrintDebugString("[INFO]: In AccessBridgeDialog - Got WM_COPYDATA from ourselves");
             } else {
-                //DEBUG_CODE(sprintf(buffer, "Got WM_COPYDATA from HWND %p", wParam));
-                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer));
+                PrintDebugString("[INFO]: In AccessBridgeDialog - Got WM_COPYDATA from HWND %p", wParam);
                 sentToUs = (COPYDATASTRUCT *) lParam;
                 package = (char *) sentToUs->lpData;
                 theJavaAccessBridge->processPackage(package, sentToUs->cbData);
@@ -149,18 +127,16 @@
             // wParam == sourceHwnd
             // lParam == buffer size in shared memory
             if (theDialogWindow == (HWND) wParam) {
-                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_MESSAGE_WAITING from ourselves"));
+                PrintDebugString("[INFO]: In AccessBridgeDialog - Got AB_MESSAGE_WAITING from ourselves");
             } else {
-                //DEBUG_CODE(sprintf(buffer, "Got AB_MESSAGE_WAITING from HWND %p", wParam));
-                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer));
-                LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, lParam);
+                PrintDebugString("[INFO]: In AccessBridgeDialog - Got AB_MESSAGE_WAITING from HWND %p", wParam);
+                LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, (long) lParam);
             }
             break;
 
             // a JavaAccessBridge DLL is going away
         case AB_DLL_GOING_AWAY:
-            // wParam == sourceHwnd
-            //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_DLL_GOING_AWAY message"));
+            PrintDebugString("[INFO]: In AccessBridgeDialog - Got AB_DLL_GOING_AWAY message");
             theJavaAccessBridge->WindowsATDestroyed((HWND) wParam);
             break;
 
@@ -171,6 +147,7 @@
                 // A new Windows AT just said "hi";
                 // say "hi" back so it can mate up with us
                 // otherwise don't do anything (e.g. don't set up data structures yet)
+                PrintDebugString("[INFO]: In AccessBridgeDialog - Got theFromWindowsHelloMsgID message");
                 theJavaAccessBridge->postHelloToWindowsDLLMsg((HWND) wParam);
             }
         }
@@ -190,6 +167,7 @@
 JavaAccessBridge::JavaAccessBridge(HINSTANCE hInstance) {
     windowsInstance = hInstance;
     ATs = (AccessBridgeATInstance *) 0;
+    initializeFileLogger("java_access_bridge");
     initBroadcastMessageIDs();          // get the unique to us broadcast msg. IDs
 }
 
@@ -202,7 +180,7 @@
 JavaAccessBridge::~JavaAccessBridge() {
     // inform all other AccessBridges that we're going away
 
-    PrintDebugString("\r\nin JavaAccessBridge::~JavaAccessBridge()");
+    PrintDebugString("[INFO]: in JavaAccessBridge::~JavaAccessBridge()");
 
     // Send a shutdown message for those applications like StarOffice that do
     // send a shutdown message themselves.
@@ -210,13 +188,13 @@
 
     AccessBridgeATInstance *current = ATs;
     while (current != (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  telling %p we're going away", current->winAccessBridgeWindow);
+        PrintDebugString("[INFO]:  telling %p we're going away", current->winAccessBridgeWindow);
                 SendMessage(current->winAccessBridgeWindow,
                     AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0);
         current = current->nextATInstance;
     }
 
-    PrintDebugString("  finished telling ATs about our demise");
+    PrintDebugString("[INFO]:  finished telling ATs about our demise");
 
         if(JavaBridgeThreadId)
                 {
@@ -226,8 +204,9 @@
 
     delete ATs;
 
-    PrintDebugString("  finished deleting ATs");
-    PrintDebugString("GOODBYE CRUEL WORLD...");
+    PrintDebugString("[INFO]:   finished deleting ATs");
+    PrintDebugString("[INFO]: GOODBYE CRUEL WORLD...");
+    finalizeFileLogger();
 }
 
 
@@ -235,17 +214,17 @@
 JavaAccessBridge::javaRun(JNIEnv *env, jobject obj) {
     MSG msg;
 
-    PrintDebugString("JavaAccessBridge::javaRun(%p, %p) called", env, obj);
+    PrintDebugString("[INFO]: JavaAccessBridge::javaRun(%p, %p) called", env, obj);
 
     if (env->GetJavaVM(&javaVM) != 0) {
         return; // huh!?!?!
     }
-    PrintDebugString("  -> javaVM = %p", javaVM);
+    PrintDebugString("[INFO]:   -> javaVM = %p", javaVM);
 
     if (javaVM->AttachCurrentThread((void **) &windowsThreadJNIEnv, NULL) != 0) {
         return; // huh!?!?!
     }
-    PrintDebugString("  -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv);
+    PrintDebugString("[INFO]:  -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv);
 
     javaThreadABObject = env->NewGlobalRef(obj);
     windowsThreadABObject = windowsThreadJNIEnv->NewGlobalRef(obj);
@@ -255,7 +234,7 @@
     if (javaThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
         return;         // couldn't build our entry points; let's get out of here!
     }
-    PrintDebugString("  all Java thread entry points successfully found.");
+    PrintDebugString("[INFO]:   all Java thread entry points successfully found.");
 
     // initialize the Windows thread AccessBridge entry points
     windowsThreadEntryPoints = new AccessBridgeJavaEntryPoints(windowsThreadJNIEnv,
@@ -263,12 +242,12 @@
     if (windowsThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
         return;         // couldn't build our entry points; let's get out of here!
     }
-    PrintDebugString("  all Windows thread entry points successfully found.");
+    PrintDebugString("[INFO]:   all Windows thread entry points successfully found.");
 
 
     // open our window
     if (initWindow() == TRUE) {
-        PrintDebugString("  Window created.  HWND = %p", dialogWindow);
+        PrintDebugString("[INFO]:   Window created.  HWND = %p", dialogWindow);
 
         // post a broadcast msg.; let other AccessBridge DLLs know we exist
         postHelloToWindowsDLLMsg(HWND_BROADCAST);
@@ -279,7 +258,7 @@
             DispatchMessage(&msg);
         }
     } else {
-        PrintDebugString("  FAILED TO CREATE WINDOW!!!");
+        PrintDebugString("[ERROR]:   FAILED TO CREATE WINDOW!!!");
     }
 
     javaVM->DetachCurrentThread();
@@ -326,9 +305,9 @@
  */
 void
 JavaAccessBridge::postHelloToWindowsDLLMsg(HWND destHwnd) {
-    PrintDebugString("\r\nin JavaAccessBridge::postHelloToWindowsDLLMsg");
-    PrintDebugString("  calling PostMessage(%p, %X, %p, %p)",
-                     destHwnd, theFromJavaHelloMsgID, dialogWindow, javaVM);
+    PrintDebugString("[INFO]: In JavaAccessBridge::postHelloToWindowsDLLMsg");
+    PrintDebugString("[INFO]:   calling PostMessage(%p, %X, %p, %p)",
+                     destHwnd, theFromJavaHelloMsgID, dialogWindow, dialogWindow);
     PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) dialogWindow);
 }
 
@@ -358,10 +337,10 @@
 void
 JavaAccessBridge::sendJavaEventPackage(char *buffer, int bufsize, long type) {
 
-    PrintDebugString("JavaAccessBridge::sendJavaEventPackage(), type = %X", type);
+    PrintDebugString("[INFO]: JavaAccessBridge::sendJavaEventPackage(), type = %X", type);
 
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
     }
 
     AccessBridgeATInstance *ati = ATs;
@@ -378,10 +357,10 @@
 void
 JavaAccessBridge::sendAccessibilityEventPackage(char *buffer, int bufsize, long type) {
 
-    PrintDebugString("JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type);
+    PrintDebugString("[INFO]: JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type);
 
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR] ATs == 0! (shouldn't happen here!)");
     }
 
     AccessBridgeATInstance *ati = ATs;
@@ -406,11 +385,11 @@
 JavaAccessBridge::receiveMemoryPackage(HWND srcWindow, long bufsize) {
     char *IPCview;
 
-    PrintDebugString("\r\nJavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize);
+    PrintDebugString("[INFO]: JavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize);
 
     // look-up the appropriate IPCview based on the srcHWND of the Windows AccessBridge DLL
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR! - ATs == 0 (shouldn't happen in receiveMemoryPackage()!");
+        PrintDebugString("[ERROR]: - ATs == 0 (shouldn't happen in receiveMemoryPackage()!");
         return FALSE;
     }
     AccessBridgeATInstance *ati = ATs->findABATInstanceFromATHWND(srcWindow);
@@ -433,7 +412,7 @@
 
     } else {
         //DEBUG_CODE(AppendToCallInfo("ERROR receiving memory package: couldn't find srcWindow"));
-        PrintDebugString("ERROR receiving memory package: couldn't find srcWindow");
+        PrintDebugString("[ERROR]: receiving memory package: couldn't find srcWindow");
         return FALSE;
     }
 }
@@ -445,11 +424,11 @@
  */
 LRESULT
 JavaAccessBridge::processPackage(char *buffer, int bufsize) {
-    PrintDebugString("\r\nProcessing package sent from Windows, bufsize = %d:", bufsize);
+    PrintDebugString("[INFO]: Processing package sent from Windows, bufsize = %d:", bufsize);
 
     PackageType *type = (PackageType *) buffer;
     LRESULT returnVal = 0;
-    PrintDebugString("  PackageType = %X:", *type);
+    PrintDebugString("[INFO]:  PackageType = %X:", *type);
     jobject rAC;
 
     switch (*type) {
@@ -458,13 +437,13 @@
     case cMemoryMappedFileCreatedPackage:
         // Windows is telling us it created a memory mapped file for us to use
         // in repsonding to various information querying packages (see below)
-        PrintDebugString("   type == cMemoryMappedFileCreatedPackage");
+        PrintDebugString("[INFO]:   type == cMemoryMappedFileCreatedPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage))) {
             MemoryMappedFileCreatedPackage *pkg =
                 (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType));
             returnVal = MemoryMappedFileCreated((HWND)ABLongToHandle(pkg->bridgeWindow), pkg->filename);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage));
         }
         break;
@@ -472,84 +451,84 @@
         // ------------ information querying packages ------------------
 
     case cReleaseJavaObjectPackage:
-        PrintDebugString("   type == cReleaseJavaObjectPackage");
+        PrintDebugString("[INFO]:   type == cReleaseJavaObjectPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage))) {
             ReleaseJavaObjectPackage *pkg =
                 (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType));
             releaseJavaObject((jobject)pkg->object);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage));
         }
         break;
 
     case cGetAccessBridgeVersionPackage:
-        PrintDebugString("   type == cGetAccessBridgeVersionPackage");
+        PrintDebugString("[INFO]:   type == cGetAccessBridgeVersionPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage))) {
             GetAccessBridgeVersionPackage *pkg =
                 (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getVersionInfo(&(pkg->rVersionInfo));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage));
         }
         break;
 
     case cIsJavaWindowPackage:
-        PrintDebugString("   type == cIsJavaWindowPackage");
+        PrintDebugString("[INFO]:   type == cIsJavaWindowPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(IsJavaWindowPackage))) {
             IsJavaWindowPackage *pkg =
                 (IsJavaWindowPackage *) (buffer + sizeof(PackageType));
             pkg->rResult =
                 windowsThreadEntryPoints->isJavaWindow(pkg->window);
-            PrintDebugString("     -> returning result = %d", pkg->rResult);
+            PrintDebugString("[INFO]:     -> returning result = %d", pkg->rResult);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(IsJavaWindowPackage));
         }
         break;
 
     case cIsSameObjectPackage:
-        PrintDebugString("   type == cIsSameObjectPackage");
+        PrintDebugString("[INFO]:   type == cIsSameObjectPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(IsSameObjectPackage))) {
             IsSameObjectPackage *pkg =
                 (IsSameObjectPackage *) (buffer + sizeof(PackageType));
             pkg->rResult =
                 windowsThreadEntryPoints->isSameObject((jobject)pkg->obj1, (jobject)pkg->obj2);
-            PrintDebugString("     -> returning result = %d", pkg->rResult);
+            PrintDebugString("[INFO]:     -> returning result = %d", pkg->rResult);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(IsSameObjectPackage));
         }
         break;
 
 
     case cGetAccessibleContextFromHWNDPackage:
-        PrintDebugString("   type == cGetAccessibleContextFromHWNDPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleContextFromHWNDPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage))) {
             GetAccessibleContextFromHWNDPackage *pkg =
                 (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType));
             rAC = windowsThreadEntryPoints->getAccessibleContextFromHWND(pkg->window);
             pkg->rAccessibleContext = (JOBJECT64)rAC;
             pkg->rVMID = HandleToLong(dialogWindow);
-            PrintDebugString("     -> returning AC = %p, vmID = %X", rAC, pkg->rVMID);
+            PrintDebugString("[INFO]:      -> returning AC = %p, vmID = %X", rAC, pkg->rVMID);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage));
         }
         break;
 
 
     case cGetHWNDFromAccessibleContextPackage:
-        PrintDebugString("   type == cGetHWNDFromAccessibleContextPackage");
+        PrintDebugString("[INFO]:    type == cGetHWNDFromAccessibleContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage))) {
             GetHWNDFromAccessibleContextPackage *pkg =
                 (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType));
             pkg->rHWND =
                 ABHandleToLong( windowsThreadEntryPoints->getHWNDFromAccessibleContext((jobject)pkg->accessibleContext) );
-            PrintDebugString("     -> returning HWND = %p", pkg->rHWND);
+            PrintDebugString("[INFO]:     -> returning HWND = %p", pkg->rHWND);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage));
         }
         break;
@@ -558,15 +537,15 @@
         /* ===== utility methods ===== */
 
     case cSetTextContentsPackage:
-        PrintDebugString("   type == cSetTextContentsPackage");
+        PrintDebugString("[INFO]:   type == cSetTextContentsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(SetTextContentsPackage))) {
             SetTextContentsPackage *pkg =
                 (SetTextContentsPackage *) (buffer + sizeof(PackageType));
             pkg->rResult =
                 windowsThreadEntryPoints->setTextContents((jobject)pkg->accessibleContext, pkg->text);
-            PrintDebugString("     -> returning result = %d", pkg->rResult);
+            PrintDebugString("[INFO]:     -> returning result = %d", pkg->rResult);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(SetTextContentsPackage));
         }
         break;
@@ -577,75 +556,76 @@
                 (GetParentWithRolePackage *) (buffer + sizeof(PackageType));
             rAC = windowsThreadEntryPoints->getParentWithRole((jobject)pkg->accessibleContext, pkg->role);
             pkg->rAccessibleContext = (JOBJECT64)rAC;
-            PrintDebugString("   type == cGetParentWithRolePackage");
-            PrintDebugString("     pkg->vmID: %X", pkg->vmID);
-            PrintDebugString("     pkg->accessibleContext: %p", (jobject)pkg->accessibleContext);
-            PrintDebugString("     pkg->role: %ls", pkg->role);
-            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+            PrintDebugString("[INFO]:   type == cGetParentWithRolePackage\n"\
+                             "     pkg->vmID: %X"\
+                             "     pkg->accessibleContext: %p"\
+                             "     pkg->role: %ls"\
+                             "     -> returning rAccessibleContext = %p"\
+                , pkg->vmID, (jobject)pkg->accessibleContext, pkg->role, rAC);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetParentWithRolePackage));
         }
         break;
 
     case cGetTopLevelObjectPackage:
-        PrintDebugString("   type == cGetTopLevelObjectPackage");
+        PrintDebugString("[INFO]:   type == cGetTopLevelObjectPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetTopLevelObjectPackage))) {
             GetTopLevelObjectPackage *pkg =
                 (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType));
             rAC = windowsThreadEntryPoints->getTopLevelObject((jobject)pkg->accessibleContext);
             pkg->rAccessibleContext = (JOBJECT64)rAC;
-            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+            PrintDebugString("[INFO]:      -> returning rAccessibleContext = %p", rAC);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetTopLevelObjectPackage));
         }
         break;
 
     case cGetParentWithRoleElseRootPackage:
-        PrintDebugString("   type == cGetParentWithRoleElseRootPackage");
+        PrintDebugString("[INFO]:   type == cGetParentWithRoleElseRootPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage))) {
             GetParentWithRoleElseRootPackage *pkg =
                 (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType));
             rAC = windowsThreadEntryPoints->getParentWithRoleElseRoot((jobject)pkg->accessibleContext, pkg->role);
             pkg->rAccessibleContext = (JOBJECT64)rAC;
-            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+            PrintDebugString("[INFO]:      -> returning rAccessibleContext = %p", rAC);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage));
         }
         break;
 
     case cGetObjectDepthPackage:
-        PrintDebugString("   type == cGetObjectDepthPackage");
+        PrintDebugString("[INFO]:   type == cGetObjectDepthPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetObjectDepthPackage))) {
             GetObjectDepthPackage *pkg =
                 (GetObjectDepthPackage *) (buffer + sizeof(PackageType));
             pkg->rResult =
                 windowsThreadEntryPoints->getObjectDepth((jobject)pkg->accessibleContext);
-            PrintDebugString("     -> returning rResult = %d", pkg->rResult);
+            PrintDebugString("[INFO]:     -> returning rResult = %d", pkg->rResult);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetObjectDepthPackage));
         }
         break;
 
     case cGetActiveDescendentPackage:
-        PrintDebugString("   type == cGetActiveDescendentPackage");
+        PrintDebugString("[INFO]:   type == cGetActiveDescendentPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetActiveDescendentPackage))) {
             GetActiveDescendentPackage *pkg =
                 (GetActiveDescendentPackage *) (buffer + sizeof(PackageType));
             rAC = windowsThreadEntryPoints->getActiveDescendent((jobject)pkg->accessibleContext);
             pkg->rAccessibleContext = (JOBJECT64)rAC;
-            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+            PrintDebugString("[INFO]:  -> returning rAccessibleContext = %p", rAC);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetActiveDescendentPackage));
         }
         break;
 
     case cGetAccessibleContextAtPackage:
-        PrintDebugString("   type == cGetAccessibleContextAtPackage");
+        PrintDebugString("[INFO]:   type == cGetAccessibleContextAtPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage))) {
             GetAccessibleContextAtPackage *pkg =
                 (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType));
@@ -653,13 +633,13 @@
                 windowsThreadEntryPoints->getAccessibleContextAt(pkg->x, pkg->y,
                                                                  (jobject)pkg->AccessibleContext);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage));
         }
         break;
 
     case cGetAccessibleContextWithFocusPackage:
-        PrintDebugString("   type == cGetAccessibleContextWithFocusPackage");
+        PrintDebugString("[INFO]:   type == cGetAccessibleContextWithFocusPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage))) {
             GetAccessibleContextWithFocusPackage *pkg =
                 (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
@@ -667,46 +647,46 @@
                 windowsThreadEntryPoints->getAccessibleContextWithFocus();
                         pkg->rVMID =  HandleToLong(dialogWindow);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage));
         }
         break;
 
     case cGetAccessibleContextInfoPackage:
-        PrintDebugString("   type == cGetAccessibleContextInfoPackage");
+        PrintDebugString("[INFO]:   type == cGetAccessibleContextInfoPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage))) {
             GetAccessibleContextInfoPackage *pkg =
                 (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleContextInfo(
                                                                (jobject)pkg->AccessibleContext, &(pkg->rAccessibleContextInfo));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage));
         }
         break;
 
     case cGetAccessibleChildFromContextPackage:
-        PrintDebugString("   type == cGetAccessibleChildFromContextPackage");
+        PrintDebugString("[INFO]:   type == cGetAccessibleChildFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage))) {
             GetAccessibleChildFromContextPackage *pkg =
                 (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType));
             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleChildFromContext(
                                                                                               (jobject)pkg->AccessibleContext, pkg->childIndex);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage));
         }
         break;
 
     case cGetAccessibleParentFromContextPackage:
-        PrintDebugString("   type == cGetAccessibleParentFromContextPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleParentFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage))) {
             GetAccessibleParentFromContextPackage *pkg =
                 (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType));
             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleParentFromContext(
                                                                                                (jobject)pkg->AccessibleContext);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage));
         }
         break;
@@ -714,106 +694,106 @@
         // ------------ begin AccessibleTable packages ------------------
 
     case cGetAccessibleTableInfoPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableInfoPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableInfoPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage))) {
             GetAccessibleTableInfoPackage *pkg =
                 (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTableInfo((jobject)pkg->accessibleContext,
                                                              &(pkg->rTableInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage));
         }
         break;
 
     case cGetAccessibleTableCellInfoPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableCellInfoPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableCellInfoPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage))) {
             GetAccessibleTableCellInfoPackage *pkg =
                 (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTableCellInfo((jobject)pkg->accessibleTable, pkg->row,
                                                                  pkg->column, &(pkg->rTableCellInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage));
         }
         break;
 
     case cGetAccessibleTableRowHeaderPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableRowHeaderPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableRowHeaderPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage))) {
             GetAccessibleTableRowHeaderPackage *pkg =
                 (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTableRowHeader((jobject)pkg->accessibleContext,
                                                                   &(pkg->rTableInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage));
         }
         break;
 
     case cGetAccessibleTableColumnHeaderPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableColumnHeaderPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableColumnHeaderPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage))) {
             GetAccessibleTableColumnHeaderPackage *pkg =
                 (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTableColumnHeader((jobject)pkg->accessibleContext,
                                                                      &(pkg->rTableInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage));
         }
         break;
 
 
     case cGetAccessibleTableRowDescriptionPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableRowDescriptionPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableRowDescriptionPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage))) {
             GetAccessibleTableRowDescriptionPackage *pkg =
                 (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType));
             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableRowDescription(
                                                                                                  (jobject)pkg->accessibleContext, pkg->row);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage));
         }
         break;
 
     case cGetAccessibleTableColumnDescriptionPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableColumnDescriptionPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableColumnDescriptionPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage))) {
             GetAccessibleTableColumnDescriptionPackage *pkg =
                 (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType));
             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableColumnDescription(
                                                                                                     (jobject)pkg->accessibleContext, pkg->column);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage));
         }
         break;
 
     case cGetAccessibleTableColumnSelectionCountPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionCountPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableColumnSelectionCountPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage))) {
             GetAccessibleTableColumnSelectionCountPackage *pkg =
                 (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType));
             pkg->rCount = windowsThreadEntryPoints->getAccessibleTableColumnSelectionCount(
                                                                                            (jobject)pkg->accessibleTable);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage));
         }
         break;
 
     case cGetAccessibleTableRowSelectionCountPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionCountPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableRowSelectionCountPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage))) {
             GetAccessibleTableRowSelectionCountPackage *pkg =
                 (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType));
@@ -821,114 +801,114 @@
             pkg->rCount = windowsThreadEntryPoints->getAccessibleTableRowSelectionCount(
                                                                                         (jobject)pkg->accessibleTable);
 
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage));
         }
         break;
 
     case cIsAccessibleTableRowSelectedPackage:
-        PrintDebugString("   ##### type == cIsAccessibleTableRowSelectedPackage");
+        PrintDebugString("[INFO]:    ##### type == cIsAccessibleTableRowSelectedPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage))) {
             IsAccessibleTableRowSelectedPackage *pkg =
                 (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType));
             pkg->rResult = windowsThreadEntryPoints->isAccessibleTableRowSelected(
                                                                                   (jobject)pkg->accessibleTable, pkg->row);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage));
         }
         break;
 
     case cIsAccessibleTableColumnSelectedPackage:
-        PrintDebugString("   ##### type == cIsAccessibleTableColumnSelectedPackage");
+        PrintDebugString("[INFO]:    ##### type == cIsAccessibleTableColumnSelectedPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage))) {
             IsAccessibleTableColumnSelectedPackage *pkg =
                 (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType));
             pkg->rResult = windowsThreadEntryPoints->isAccessibleTableColumnSelected(
                                                                                      (jobject)pkg->accessibleTable, pkg->column);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage));
         }
         break;
 
     case cGetAccessibleTableColumnSelectionsPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionsPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableColumnSelectionsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage))) {
             GetAccessibleTableColumnSelectionsPackage *pkg =
                 (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType));
-            PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count);
+            PrintDebugString("[INFO]:      ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count);
             windowsThreadEntryPoints->getAccessibleTableColumnSelections(
                                                                          (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections);
 
             for (int i = 0; i < pkg->count; i++) {
-                PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]);
+                PrintDebugString("[INFO]:      ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]);
             }
 
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage));
         }
         break;
 
 
     case cGetAccessibleTableRowSelectionsPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionsPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableRowSelectionsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage))) {
             GetAccessibleTableRowSelectionsPackage *pkg =
                 (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTableRowSelections(
                                                                       (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage));
         }
         break;
 
     case cGetAccessibleTableRowPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableRowPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableRowPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage))) {
             GetAccessibleTableRowPackage *pkg =
                 (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType));
             pkg->rRow = windowsThreadEntryPoints->getAccessibleTableRow(
                                                                         (jobject)pkg->accessibleTable, pkg->index);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage));
         }
         break;
 
     case cGetAccessibleTableColumnPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableColumnPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableColumnPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage))) {
             GetAccessibleTableColumnPackage *pkg =
                 (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType));
             pkg->rColumn = windowsThreadEntryPoints->getAccessibleTableColumn(
                                                                               (jobject)pkg->accessibleTable, pkg->index);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage));
         }
         break;
 
     case cGetAccessibleTableIndexPackage:
-        PrintDebugString("   ##### type == cGetAccessibleTableIndexPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleTableIndexPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage))) {
             GetAccessibleTableIndexPackage *pkg =
                 (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType));
             pkg->rIndex = windowsThreadEntryPoints->getAccessibleTableIndex(
                                                                             (jobject)pkg->accessibleTable, pkg->row, pkg->column);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage));
         }
         break;
@@ -939,15 +919,15 @@
         // ------------ begin AccessibleRelationSet packages ------------------
 
     case cGetAccessibleRelationSetPackage:
-        PrintDebugString("   ##### type == cGetAccessibleRelationSetPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleRelationSetPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage))) {
             GetAccessibleRelationSetPackage *pkg =
                 (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleRelationSet(
                                                                (jobject)pkg->accessibleContext, &(pkg->rAccessibleRelationSetInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage));
         }
         break;
@@ -957,85 +937,85 @@
         // ------------ begin AccessibleHypertext packages ------------------
 
     case cGetAccessibleHypertextPackage:
-        PrintDebugString("   ##### type == cGetAccessibleHypertextPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleHypertextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage))) {
             GetAccessibleHypertextPackage *pkg =
                 (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleHypertext(
                                                              (jobject)pkg->accessibleContext, &(pkg->rAccessibleHypertextInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage));
         }
         break;
 
     case cActivateAccessibleHyperlinkPackage:
-        PrintDebugString("   ##### type == cActivateAccessibleHyperlinkPackage");
+        PrintDebugString("[INFO]:    ##### type == cActivateAccessibleHyperlinkPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage))) {
             ActivateAccessibleHyperlinkPackage *pkg =
                 (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
             pkg->rResult = windowsThreadEntryPoints->activateAccessibleHyperlink(
                                                                                  (jobject)pkg->accessibleContext, (jobject)pkg->accessibleHyperlink);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage));
         }
         break;
 
     case cGetAccessibleHyperlinkCountPackage:
-        PrintDebugString("   ##### type == cGetAccessibleHyperlinkCountPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleHyperlinkCountPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage))) {
             GetAccessibleHyperlinkCountPackage *pkg =
                 (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType));
             pkg->rLinkCount = windowsThreadEntryPoints->getAccessibleHyperlinkCount(
                                                                                     (jobject)pkg->accessibleContext);
-            PrintDebugString("   ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount);
+            PrintDebugString("[INFO]:    ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount);
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage));
         }
         break;
 
     case cGetAccessibleHypertextExtPackage:
-        PrintDebugString("   ##### type == cGetAccessibleHypertextExtPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleHypertextExtPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage))) {
             GetAccessibleHypertextExtPackage *pkg =
                 (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType));
             pkg->rSuccess = windowsThreadEntryPoints->getAccessibleHypertextExt(
                                                                                 (jobject)pkg->accessibleContext, pkg->startIndex, &(pkg->rAccessibleHypertextInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage));
         }
         break;
 
     case cGetAccessibleHypertextLinkIndexPackage:
-        PrintDebugString("   ##### type == cGetAccessibleHypertextLinkIndexPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleHypertextLinkIndexPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage))) {
             GetAccessibleHypertextLinkIndexPackage *pkg =
                 (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType));
             pkg->rLinkIndex = windowsThreadEntryPoints->getAccessibleHypertextLinkIndex(
                                                                                         (jobject)pkg->hypertext, pkg->charIndex);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage));
         }
         break;
 
     case cGetAccessibleHyperlinkPackage:
-        PrintDebugString("   ##### type == cGetAccessibleHyperlinkPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleHyperlinkPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage))) {
             GetAccessibleHyperlinkPackage *pkg =
                 (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleHyperlink((jobject)pkg->hypertext, pkg->linkIndex,
                                                              &(pkg->rAccessibleHyperlinkInfo));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage));
         }
         break;
@@ -1045,59 +1025,59 @@
         // ------------ begin Accessible KeyBindings, Icons and Actions
 
     case cGetAccessibleKeyBindingsPackage:
-        PrintDebugString("   ##### type == cGetAccessibleKeyBindingsPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleKeyBindingsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage))) {
             GetAccessibleKeyBindingsPackage *pkg =
                 (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleKeyBindings (
                                                                 (jobject)pkg->accessibleContext, &(pkg->rAccessibleKeyBindings));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage));
         }
         break;
 
     case cGetAccessibleIconsPackage:
-        PrintDebugString("   ##### type == cGetAccessibleIconsPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleIconsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleIconsPackage))) {
             GetAccessibleIconsPackage *pkg =
                 (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleIcons (
                                                           (jobject)pkg->accessibleContext, &(pkg->rAccessibleIcons));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleIconsPackage));
         }
         break;
 
 
     case cGetAccessibleActionsPackage:
-        PrintDebugString("   ##### type == cGetAccessibleActionsPackage");
+        PrintDebugString("[INFO]:    ##### type == cGetAccessibleActionsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleActionsPackage))) {
             GetAccessibleActionsPackage *pkg =
                 (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleActions (
                                                             (jobject)pkg->accessibleContext, &(pkg->rAccessibleActions));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleActionsPackage));
         }
         break;
 
     case cDoAccessibleActionsPackage:
-        PrintDebugString("   ##### type == cDoAccessibleActionsPackage");
+        PrintDebugString("[INFO]:    ##### type == cDoAccessibleActionsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(DoAccessibleActionsPackage))) {
             DoAccessibleActionsPackage *pkg =
                 (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType));
             pkg->rResult =
                 windowsThreadEntryPoints->doAccessibleActions((jobject)pkg->accessibleContext, &(pkg->actionsToDo),
                                                               &(pkg->failure));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(DoAccessibleActionsPackage));
         }
         break;
@@ -1105,50 +1085,50 @@
         // ------------ begin addtional methods for Teton
 
     case cGetVirtualAccessibleNamePackage:
-        PrintDebugString("   ##### type == GetVirtualAccessibleNamePackage");
+        PrintDebugString("[INFO]:    ##### type == GetVirtualAccessibleNamePackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage))) {
             GetVirtualAccessibleNamePackage *pkg =
                 (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getVirtualAccessibleName ((const jobject)pkg->accessibleContext,
                                                              pkg->rName,
                                                              pkg->len);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage));
         }
         break;
 
     case cRequestFocusPackage:
-        PrintDebugString("   ##### type == RequestFocusPackage");
+        PrintDebugString("[INFO]:    ##### type == RequestFocusPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(RequestFocusPackage))) {
             RequestFocusPackage *pkg =
                 (RequestFocusPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->requestFocus (
                                                     (jobject)pkg->accessibleContext);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(RequestFocusPackage));
         }
         break;
 
     case cSelectTextRangePackage:
-        PrintDebugString("   ##### type == SelectTextRangePackage");
+        PrintDebugString("[INFO]:    ##### type == SelectTextRangePackage");
         if (bufsize == (sizeof(PackageType) + sizeof(SelectTextRangePackage))) {
             SelectTextRangePackage *pkg =
                 (SelectTextRangePackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->selectTextRange (
                                                        (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(SelectTextRangePackage));
         }
         break;
 
     case cGetTextAttributesInRangePackage:
-        PrintDebugString("   ##### type == GetTextAttributesInRangePackage");
+        PrintDebugString("[INFO]:    ##### type == GetTextAttributesInRangePackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage))) {
             GetTextAttributesInRangePackage *pkg =
                 (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType));
@@ -1156,30 +1136,30 @@
                                                                 (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex,
                                                                 (AccessibleTextAttributesInfo *)&(pkg->attributes),
                                                                 &(pkg->rLength));
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage));
         }
         break;
 
 
     case cGetVisibleChildrenCountPackage:
-        PrintDebugString("   ##### type == GetVisibleChildrenCountPackage");
+        PrintDebugString("[INFO]:    ##### type == GetVisibleChildrenCountPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage))) {
             GetVisibleChildrenCountPackage *pkg =
                 (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType));
             pkg->rChildrenCount = windowsThreadEntryPoints->getVisibleChildrenCount ((jobject)pkg->accessibleContext);
 
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage));
         }
         break;
 
     case cGetVisibleChildrenPackage:
-        PrintDebugString("   ##### type == GetVisibleChildrenPackage");
+        PrintDebugString("[INFO]:    ##### type == GetVisibleChildrenPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenPackage))) {
             GetVisibleChildrenPackage *pkg =
                 (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType));
@@ -1187,23 +1167,23 @@
                                                                           pkg->startIndex,
                                                                           &(pkg->rVisibleChildrenInfo));
 
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenPackage));
         }
         break;
 
     case cSetCaretPositionPackage:
-        PrintDebugString("   ##### type == SetCaretPositionPackage");
+        PrintDebugString("[INFO]:    ##### type == SetCaretPositionPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(SetCaretPositionPackage))) {
             SetCaretPositionPackage *pkg =
                 (SetCaretPositionPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->setCaretPosition (
                                                         (jobject)pkg->accessibleContext, pkg->position);
-            PrintDebugString("   ##### processing succeeded");
+            PrintDebugString("[INFO]:    ##### processing succeeded");
         } else {
-            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    ##### processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(SetCaretPositionPackage));
         }
         break;
@@ -1215,105 +1195,105 @@
         // ------------ Accessible Text packages ------------------
 
     case cGetAccessibleTextInfoPackage:
-        PrintDebugString("   type == cGetAccessibleTextInfoPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleTextInfoPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage))) {
             GetAccessibleTextInfoPackage *pkg =
                 (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTextInfo((jobject)pkg->AccessibleContext,
                                                             &(pkg->rTextInfo), pkg->x, pkg->y);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
         }
         break;
 
     case cGetAccessibleTextItemsPackage:
-        PrintDebugString("   type == cGetAccessibleTextItemsPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleTextItemsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage))) {
             GetAccessibleTextItemsPackage *pkg =
                 (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTextItems((jobject)pkg->AccessibleContext,
                                                              &(pkg->rTextItemsInfo), pkg->index);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
         }
         break;
 
     case cGetAccessibleTextSelectionInfoPackage:
-        PrintDebugString("   type == cGetAccessibleTextSelectionInfoPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleTextSelectionInfoPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage))) {
             GetAccessibleTextSelectionInfoPackage *pkg =
                 (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTextSelectionInfo(
                                                                      (jobject)pkg->AccessibleContext, &(pkg->rTextSelectionItemsInfo));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage));
         }
         break;
 
     case cGetAccessibleTextAttributeInfoPackage:
-        PrintDebugString("   type == cGetAccessibleTextAttributeInfoPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleTextAttributeInfoPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage))) {
             GetAccessibleTextAttributeInfoPackage *pkg =
                 (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTextAttributes(
                                                                   (jobject)pkg->AccessibleContext, pkg->index, (AccessibleTextAttributesInfo *) &(pkg->rAttributeInfo));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage));
         }
         break;
 
     case cGetAccessibleTextRectInfoPackage:
-        PrintDebugString("   type == cGetAccessibleTextRectInfoPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleTextRectInfoPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage))) {
             GetAccessibleTextRectInfoPackage *pkg =
                 (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTextRect((jobject)pkg->AccessibleContext,
                                                             &(pkg->rTextRectInfo), pkg->index);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage));
         }
         break;
 
     case cGetCaretLocationPackage:
-        PrintDebugString("   type == cGetCaretLocationPackage");
+        PrintDebugString("[INFO]:    type == cGetCaretLocationPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetCaretLocationPackage))) {
             GetCaretLocationPackage *pkg =
                 (GetCaretLocationPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getCaretLocation((jobject)pkg->AccessibleContext,
                                                             &(pkg->rTextRectInfo), pkg->index);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetCaretLocationPackage));
         }
         break;
 
     case cGetAccessibleTextLineBoundsPackage:
-        PrintDebugString("   type == cGetAccessibleTextLineBoundsPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleTextLineBoundsPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage))) {
             GetAccessibleTextLineBoundsPackage *pkg =
                 (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTextLineBounds((jobject)pkg->AccessibleContext,
                                                                   pkg->index, &(pkg->rLineStart), &(pkg->rLineEnd));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage));
         }
         break;
 
     case cGetAccessibleTextRangePackage:
-        PrintDebugString("   type == cGetAccessibleTextRangePackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleTextRangePackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage))) {
             GetAccessibleTextRangePackage *pkg =
                 (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getAccessibleTextRange((jobject)pkg->AccessibleContext,
                                                              pkg->start, pkg->end, (wchar_t *) &(pkg->rText), (sizeof(pkg->rText) / sizeof(wchar_t)));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage));
         }
         break;
@@ -1322,40 +1302,40 @@
         // ------------ Accessible Value packages ------------------
 
     case cGetCurrentAccessibleValueFromContextPackage:
-        PrintDebugString("   type == cGetCurrentAccessibleValueFromContextPackage");
+        PrintDebugString("[INFO]:    type == cGetCurrentAccessibleValueFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage))) {
             GetCurrentAccessibleValueFromContextPackage *pkg =
                 (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getCurrentAccessibleValueFromContext((jobject)pkg->AccessibleContext,
                                                                            (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage));
         }
         break;
 
     case cGetMaximumAccessibleValueFromContextPackage:
-        PrintDebugString("   type == cGetMaximumAccessibleValueFromContextPackage");
+        PrintDebugString("[INFO]:    type == cGetMaximumAccessibleValueFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage))) {
             GetMaximumAccessibleValueFromContextPackage *pkg =
                 (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getMaximumAccessibleValueFromContext((jobject)pkg->AccessibleContext,
                                                                            (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage));
         }
         break;
 
     case cGetMinimumAccessibleValueFromContextPackage:
-        PrintDebugString("   type == cGetMinimumAccessibleValueFromContextPackage");
+        PrintDebugString("[INFO]:    type == cGetMinimumAccessibleValueFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage))) {
             GetMinimumAccessibleValueFromContextPackage *pkg =
                 (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->getMinimumAccessibleValueFromContext((jobject)pkg->AccessibleContext,
                                                                            (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage));
         }
         break;
@@ -1363,90 +1343,90 @@
         // ------------ Accessible Selection packages ------------------
 
     case cAddAccessibleSelectionFromContextPackage:
-        PrintDebugString("   type == cAddAccessibleSelectionFromContextPackage");
+        PrintDebugString("[INFO]:    type == cAddAccessibleSelectionFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage))) {
             AddAccessibleSelectionFromContextPackage *pkg =
                 (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->addAccessibleSelectionFromContext((jobject)pkg->AccessibleContext,
                                                                         pkg->index);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage));
         }
         break;
 
     case cClearAccessibleSelectionFromContextPackage:
-        PrintDebugString("   type == cClearAccessibleSelectionFromContextPackage");
+        PrintDebugString("[INFO]:    type == cClearAccessibleSelectionFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage))) {
             ClearAccessibleSelectionFromContextPackage *pkg =
                 (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->clearAccessibleSelectionFromContext((jobject)pkg->AccessibleContext);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage));
         }
         break;
 
     case cGetAccessibleSelectionFromContextPackage:
-        PrintDebugString("   type == cGetAccessibleSelectionFromContextPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleSelectionFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage))) {
             GetAccessibleSelectionFromContextPackage *pkg =
                 (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
             pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleSelectionFromContext(
                                                                                                   (jobject)pkg->AccessibleContext, pkg->index);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage));
         }
         break;
 
     case cGetAccessibleSelectionCountFromContextPackage:
-        PrintDebugString("   type == cGetAccessibleSelectionCountFromContextPackage");
+        PrintDebugString("[INFO]:    type == cGetAccessibleSelectionCountFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage))) {
             GetAccessibleSelectionCountFromContextPackage *pkg =
                 (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType));
             pkg->rCount = windowsThreadEntryPoints->getAccessibleSelectionCountFromContext(
                                                                                            (jobject)pkg->AccessibleContext);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage));
         }
         break;
 
     case cIsAccessibleChildSelectedFromContextPackage:
-        PrintDebugString("   type == cIsAccessibleChildSelectedFromContextPackage");
+        PrintDebugString("[INFO]:    type == cIsAccessibleChildSelectedFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage))) {
             IsAccessibleChildSelectedFromContextPackage *pkg =
                 (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType));
             pkg->rResult = windowsThreadEntryPoints->isAccessibleChildSelectedFromContext(
                                                                                           (jobject)pkg->AccessibleContext, pkg->index);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage));
         }
         break;
 
     case cRemoveAccessibleSelectionFromContextPackage:
-        PrintDebugString("   type == cRemoveAccessibleSelectionFromContextPackage");
+        PrintDebugString("[INFO]:    type == cRemoveAccessibleSelectionFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage))) {
             RemoveAccessibleSelectionFromContextPackage *pkg =
                 (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->removeAccessibleSelectionFromContext((jobject)pkg->AccessibleContext,
                                                                            pkg->index);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage));
         }
         break;
 
     case cSelectAllAccessibleSelectionFromContextPackage:
-        PrintDebugString("   type == cSelectAllAccessibleSelectionFromContextPackage");
+        PrintDebugString("[INFO]:    type == cSelectAllAccessibleSelectionFromContextPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage))) {
             SelectAllAccessibleSelectionFromContextPackage *pkg =
                 (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
             windowsThreadEntryPoints->selectAllAccessibleSelectionFromContext((jobject)pkg->AccessibleContext);
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage));
         }
         break;
@@ -1455,60 +1435,60 @@
         // ------------ event notification management packages ------------------
 
     case cAddJavaEventNotificationPackage:
-        PrintDebugString("   type = cAddJavaEventNotificationPackage");
+        PrintDebugString("[INFO]:    type = cAddJavaEventNotificationPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage))) {
             AddJavaEventNotificationPackage *pkg =
                 (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
             addJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ) );
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage));
         }
         break;
 
     case cRemoveJavaEventNotificationPackage:
-        PrintDebugString("   type = cRemoveJavaEventNotificationPackage");
+        PrintDebugString("[INFO]:    type = cRemoveJavaEventNotificationPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage))) {
             RemoveJavaEventNotificationPackage *pkg =
                 (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
             removeJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage));
         }
         break;
 
     case cAddAccessibilityEventNotificationPackage:
-        PrintDebugString("   type = cAddAccessibilityEventNotificationPackage");
+        PrintDebugString("[INFO]:    type = cAddAccessibilityEventNotificationPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage))) {
             AddAccessibilityEventNotificationPackage *pkg =
                 (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
             addAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage));
         }
         break;
 
     case cRemoveAccessibilityEventNotificationPackage:
-        PrintDebugString("   type = cRemoveAccessibilityEventNotificationPackage");
+        PrintDebugString("[INFO]:    type = cRemoveAccessibilityEventNotificationPackage");
         if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage))) {
             RemoveAccessibilityEventNotificationPackage *pkg =
                 (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
             removeAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow));
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage));
         }
         break;
 
     default:
-        PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
+        PrintDebugString("[ERROR]:    processing FAILED!! -> don't know how to handle type = %X", *type);
         returnVal = -1;
         break;
     }
 
-    PrintDebugString("   package processing completed");
+    PrintDebugString("[INFO]:    package processing completed");
     return returnVal;
 }
 
@@ -1527,17 +1507,17 @@
  */
 LRESULT
 JavaAccessBridge::MemoryMappedFileCreated(HWND ATBridgeDLLWindow, char *filename) {
-    PrintDebugString("  in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename);
+    PrintDebugString("[INFO]:   in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename);
     AccessBridgeATInstance *newAT =
         new AccessBridgeATInstance(dialogWindow, ATBridgeDLLWindow, filename, ATs);
-    PrintDebugString("    just created a new ATInstance = %p, old = %p", newAT, ATs);
+    PrintDebugString("[INFO]:     just created a new ATInstance = %p, old = %p", newAT, ATs);
     ATs = newAT;
 
     LRESULT returnVal = ATs->initiateIPC();
     if (returnVal == 0) {
-        PrintDebugString("  Successfully initiated IPC with AT!!!");
+        PrintDebugString("[INFO]:   Successfully initiated IPC with AT!!!");
     } else {
-        PrintDebugString("  ERROR: Failed to initiate IPC with AT!!!");
+        PrintDebugString("[ERROR]: Failed to initiate IPC with AT!!!");
     }
 
     return returnVal;
@@ -1550,9 +1530,9 @@
  */
 void
 JavaAccessBridge::WindowsATDestroyed(HWND ATBridgeDLLWindow) {
-    PrintDebugString("\r\nin JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow);
+    PrintDebugString("[INFO]: in JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow);
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! -> ATs == 0! (shouldn't happen here)");
+        PrintDebugString("[ERROR]: -> ATs == 0! (shouldn't happen here)");
         return;
     }
 
@@ -1564,20 +1544,20 @@
         removeJavaEventNotification(currentAT->javaEventMask, ATBridgeDLLWindow);
         removeAccessibilityEventNotification(currentAT->accessibilityEventMask, ATBridgeDLLWindow);
         delete currentAT;
-        PrintDebugString("  data structures successfully removed");
+        PrintDebugString("[INFO]:   data structures successfully removed");
     } else {
         while (currentAT != (AccessBridgeATInstance *) NULL) {
             if (currentAT->winAccessBridgeWindow == ATBridgeDLLWindow) {
                 previousAT->nextATInstance = currentAT->nextATInstance;
                 delete currentAT;
-                PrintDebugString("  data structures successfully removed");
+                PrintDebugString("[INFO]:   data structures successfully removed");
                 return;
             } else {
                 previousAT = currentAT;
                 currentAT = currentAT->nextATInstance;
             }
         }
-        PrintDebugString("  ERROR!! couldn't find matching data structures!");
+        PrintDebugString("[ERROR]: couldn't find matching data structures!");
     }
 }
 
@@ -1595,13 +1575,13 @@
  */
 void
 JavaAccessBridge::releaseJavaObject(jobject object) {
-    PrintDebugString("In JavaAccessBridge::releaseJavaObject");
-    PrintDebugString("  object X: %p", object);
+    PrintDebugString("[INFO]: In JavaAccessBridge::releaseJavaObject");
+    PrintDebugString("[INFO]:   object X: %p", object);
     if (windowsThreadJNIEnv != (JNIEnv *) 0) {
         windowsThreadJNIEnv->DeleteGlobalRef(object);
-        PrintDebugString("  global reference deleted.", object);
+        PrintDebugString("[INFO]:   global reference deleted.", object);
     } else {
-        PrintDebugString("  Error! windowsThreadJNIEnv == 0");
+        PrintDebugString("[ERROR]: windowsThreadJNIEnv == 0");
     }
 }
 
@@ -1615,23 +1595,23 @@
 JavaAccessBridge::addJavaEventNotification(jlong type, HWND DLLwindow) {
     // walk through list of ATs, find this one and add this type
     // and, if we weren't listening for these before, ask Java for 'em
-    PrintDebugString("  adding Java event type %016I64X to HWND %p", type, DLLwindow);
+    PrintDebugString("[INFO]:   adding Java event type %016I64X to HWND %p", type, DLLwindow);
     AccessBridgeATInstance *ati = ATs;
     long globalEventMask = 0;
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->winAccessBridgeWindow == DLLwindow) {
             ati->javaEventMask |= type;
-            PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
+            PrintDebugString("[INFO]:   found HWND, javaEventMask now is %X", ati->javaEventMask);
         } else {
             globalEventMask |= ati->javaEventMask;
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
+    PrintDebugString("[INFO]:   union of all Java AT event masks: %X", globalEventMask);
     if (!(globalEventMask & type)) {
         // no other ATs wanted this event;
         // start getting them from Java
-        PrintDebugString("  no other AT wanted this Java event (so not registered); adding to AccessBridge.java");
+        PrintDebugString("[INFO]:   no other AT wanted this Java event (so not registered); adding to AccessBridge.java");
         windowsThreadEntryPoints->addJavaEventNotification(type);
     }
 }
@@ -1644,23 +1624,23 @@
 JavaAccessBridge::removeJavaEventNotification(jlong type, HWND DLLwindow) {
     // walk through list of ATs, find this one and remove this type
     // and, if no other AT wants 'em either, tell Java we no longer want 'em
-    PrintDebugString("  removing Java event type %016I64X from HWND %p", type, DLLwindow);
+    PrintDebugString("[INFO]:   removing Java event type %016I64X from HWND %p", type, DLLwindow);
     AccessBridgeATInstance *ati = ATs;
     long globalEventMask = 0;
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->winAccessBridgeWindow == DLLwindow) {
             ati->javaEventMask &= (0xFFFFFFFF - type);
-            PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
+            PrintDebugString("[INFO]:   found HWND, javaEventMask now is %X", ati->javaEventMask);
         } else {
             globalEventMask |= ati->javaEventMask;
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
+    PrintDebugString("[INFO]:   union of all Java AT event masks: %X", globalEventMask);
     if (!(globalEventMask & type)) {
         // no other ATs wanted this event;
         // stop getting them from Java
-        PrintDebugString("  no other AT wanted this Java event (so can remove); removing from AccessBridge.java");
+        PrintDebugString("[INFO]:   no other AT wanted this Java event (so can remove); removing from AccessBridge.java");
         windowsThreadEntryPoints->removeJavaEventNotification(type);
     }
 }
@@ -1674,23 +1654,23 @@
 JavaAccessBridge::addAccessibilityEventNotification(jlong type, HWND DLLwindow) {
     // walk through list of ATs, find this one and add this type
     // and, if we weren't listening for these before, ask Java for 'em
-    PrintDebugString("  adding Accesibility event type %016I64X to HWND %p", type, DLLwindow);
+    PrintDebugString("[INFO]:   adding Accesibility event type %016I64X to HWND %p", type, DLLwindow);
     AccessBridgeATInstance *ati = ATs;
     long globalEventMask = 0;
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->winAccessBridgeWindow == DLLwindow) {
             ati->accessibilityEventMask |= type;
-            PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
+            PrintDebugString("[INFO]:   found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
         } else {
             globalEventMask |= ati->accessibilityEventMask;
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
+    PrintDebugString("[INFO]:   union of all Accessibility AT event masks: %X", globalEventMask);
     if (!(globalEventMask & type)) {
         // no other ATs wanted this event;
         // start getting them from Java
-        PrintDebugString("  no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java");
+        PrintDebugString("[INFO]:   no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java");
         windowsThreadEntryPoints->addAccessibilityEventNotification(type);
     }
 }
@@ -1703,23 +1683,23 @@
 JavaAccessBridge::removeAccessibilityEventNotification(jlong type, HWND DLLwindow) {
     // walk through list of ATs, find this one and remove this type
     // and, if no other AT wants 'em either, tell Java we no longer want 'em
-    PrintDebugString("  removing Accesibility event type %016I64X from HWND %p", type, DLLwindow);
+    PrintDebugString("[INFO]:   removing Accesibility event type %016I64X from HWND %p", type, DLLwindow);
     AccessBridgeATInstance *ati = ATs;
     long globalEventMask = 0;
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->winAccessBridgeWindow == DLLwindow) {
             ati->accessibilityEventMask &= (0xFFFFFFFF - type);
-            PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
+            PrintDebugString("[INFO]:   found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
         } else {
             globalEventMask |= ati->accessibilityEventMask;
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
+    PrintDebugString("[INFO]:   union of all Accessibility AT event masks: %X", globalEventMask);
     if (!(globalEventMask & type)) {
         // no other ATs wanted this event;
         // stop getting them from Java
-        PrintDebugString("  no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java");
+        PrintDebugString("[INFO]:   no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java");
         windowsThreadEntryPoints->removeAccessibilityEventNotification(type);
     }
 }
@@ -1736,13 +1716,13 @@
                                           jobject event, jobject source,
                                           jint oldValue, jint newValue) {
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -1758,17 +1738,17 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %016I64X"\
+                             "          GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             pkg->oldPosition = oldValue;
@@ -1778,7 +1758,7 @@
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyCaretChange event");
+    PrintDebugString("[INFO]:  done with propertyCaretChange event");
 }
 
 /**
@@ -1790,13 +1770,13 @@
                                                 jobject event, jobject source,
                                                 jstring oldValue, jstring newValue){
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -1813,17 +1793,17 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                             "  GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             if (oldValue != (jstring) 0) {
@@ -1864,7 +1844,7 @@
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyDescriptionChange event");
+    PrintDebugString("[INFO]:   done with propertyDescriptionChange event");
 }
 
 /**
@@ -1876,13 +1856,13 @@
                                          jobject event, jobject source,
                                          jstring oldValue, jstring newValue){
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -1899,17 +1879,17 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyNameChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                             "         GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             if (oldValue != (jstring) 0) {
@@ -1950,7 +1930,7 @@
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyNameChange event");
+    PrintDebugString("[INFO]:  done with propertyNameChange event");
 }
 
 
@@ -1962,12 +1942,12 @@
 JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj,
                                               jobject event, jobject source) {
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)",
                      env, callingObj, event, source);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -1983,24 +1963,24 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertySelectionChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %016I64X"\
+                             "          GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertySelectionChangeEvent);
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertySelectionChange event");
+    PrintDebugString("[INFO]:   done with propertySelectionChange event");
 }
 
 
@@ -2013,13 +1993,13 @@
                                           jobject event, jobject source,
                                           jstring oldValue, jstring newValue){
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -2036,17 +2016,17 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyStateChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "  GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                             "  GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             if (oldValue != (jstring) 0) {
@@ -2087,7 +2067,7 @@
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyStateChange event");
+    PrintDebugString("[INFO]:  done with propertyStateChange event");
 }
 
 
@@ -2099,12 +2079,12 @@
 JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj,
                                          jobject event, jobject source) {
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)",
                      env, callingObj, event, source);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -2120,24 +2100,24 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyTextChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p",pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                             "  GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTextChangeEvent);
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyTextChange event");
+    PrintDebugString("[INFO]:  done with propertyTextChange event");
 }
 
 
@@ -2150,13 +2130,13 @@
                                           jobject event, jobject source,
                                           jstring oldValue, jstring newValue){
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -2173,17 +2153,17 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyValueChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                             "  GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             if (oldValue != (jstring) 0) {
@@ -2224,7 +2204,7 @@
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyValueChange event");
+    PrintDebugString("[INFO]:   done with propertyValueChange event");
 }
 
 /**
@@ -2235,12 +2215,12 @@
 JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj,
                                                 jobject event, jobject source) {
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)",
                      env, callingObj, event, source);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -2256,24 +2236,24 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyVisibleDataChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                             "         GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyVisibleDataChangeEvent);
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyVisibleDataChange event");
+    PrintDebugString("[INFO]:  done with propertyVisibleDataChange event");
 }
 
 
@@ -2286,13 +2266,13 @@
                                           jobject event, jobject source,
                                           jobject oldValue, jobject newValue){
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -2308,7 +2288,7 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyChildChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:  sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
@@ -2316,22 +2296,24 @@
             pkg->oldChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue);
             pkg->newChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
-            PrintDebugString("  GlobalRef'd OldChildAC: %p", pkg->oldChildAccessibleContext);
-            PrintDebugString("  GlobalRef'd NewChildAC: %p", pkg->newChildAccessibleContext);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %p"\
+                             "  GlobalRef'd Source: %p"\
+                             "  GlobalRef'd OldChildAC: %p"\
+                             "  GlobalRef'd NewChildAC: %p"\
+                            , pkg->Event, pkg->AccessibleContextSource, pkg->oldChildAccessibleContext, pkg->newChildAccessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
-            PrintDebugString("  GlobalRef'd OldChildAC: %016I64X", pkg->oldChildAccessibleContext);
-            PrintDebugString("  GlobalRef'd NewChildAC: %016I64X", pkg->newChildAccessibleContext);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %016I64X"\
+                             "  GlobalRef'd Source: %016I64X"\
+                             "  GlobalRef'd OldChildAC: %016I64X"\
+                             "  GlobalRef'd NewChildAC: %016I64X"\
+                             , pkg->Event, pkg->AccessibleContextSource, pkg->oldChildAccessibleContext, pkg->newChildAccessibleContext);
 #endif
 
             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyChildChangeEvent);
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyChildChange event");
+    PrintDebugString("[INFO]:  done with propertyChildChange event");
 }
 
 
@@ -2344,13 +2326,13 @@
                                                      jobject event, jobject source,
                                                      jobject oldValue, jobject newValue){
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -2366,7 +2348,7 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyActiveDescendentChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:   sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
@@ -2374,22 +2356,24 @@
             pkg->oldActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue);
             pkg->newActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
-            PrintDebugString("  GlobalRef'd OldActiveDescendentAC: %p", pkg->oldActiveDescendentAccessibleContext);
-            PrintDebugString("  GlobalRef'd NewActiveDescendentAC: %p", pkg->newActiveDescendentAccessibleContext);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "  GlobalRef'd Source: %p"\
+                             "  GlobalRef'd OldActiveDescendentAC: %p"\
+                             "  GlobalRef'd NewActiveDescendentAC: %p"\
+                             , pkg->Event, pkg->AccessibleContextSource, pkg->oldActiveDescendentAccessibleContext, pkg->newActiveDescendentAccessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
-            PrintDebugString("  GlobalRef'd OldActiveDescendentAC: %016I64X", pkg->oldActiveDescendentAccessibleContext);
-            PrintDebugString("  GlobalRef'd NewActiveDescendentAC: %016I64X", pkg->newActiveDescendentAccessibleContext);
+            PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                             "  GlobalRef'd Source: %016I64X"\
+                             "  GlobalRef'd OldActiveDescendentAC: %016I64X"\
+                             "  GlobalRef'd NewActiveDescendentAC: %016I64X"\
+            , pkg->Event, pkg->AccessibleContextSource, pkg->oldActiveDescendentAccessibleContext, pkg->newActiveDescendentAccessibleContext);
 #endif
 
             ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyActiveDescendentChangeEvent);
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyActiveChange event");
+    PrintDebugString("[INFO]:  done with propertyActiveChange event");
 }
 
 /**
@@ -2401,13 +2385,13 @@
                                                jobject event, jobject source,
                                                jstring oldValue, jstring newValue){
 
-    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)",
+    PrintDebugString("[INFO]: Java_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)",
                      env, callingObj, event,
                      source, oldValue, newValue);
 
     // sanity check
     if (ATs == (AccessBridgeATInstance *) 0) {
-        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
         return;         // panic!
     }
 
@@ -2424,17 +2408,17 @@
     while (ati != (AccessBridgeATInstance *) 0) {
         if (ati->accessibilityEventMask & cPropertyTableModelChangeEvent) {
 
-            PrintDebugString("  sending to AT");
+            PrintDebugString("[INFO]:  sending to AT");
 
             // make new GlobalRefs for this AT
             pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
             pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                             "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
-            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
-            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("[INFO]:   GlobalRef'd Event: %016I64X"\
+                             "          GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
             if (oldValue != (jstring) 0) {
@@ -2475,31 +2459,31 @@
         }
         ati = ati->nextATInstance;
     }
-    PrintDebugString("  done with propertyTableModelChange event");
+    PrintDebugString("[INFO]:  done with propertyTableModelChange event");
 }
 
 
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
 #define PRINT_GLOBALREFS() \
-    PrintDebugString("  GlobalRef'd Event: %p", pkg->Event); \
-    PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+    PrintDebugString("[INFO]:   GlobalRef'd Event: %p"\
+                     "          GlobalRef'd Source: %p", pkg->Event, pkg->AccessibleContextSource);
 #else // JOBJECT64 is jlong (64 bit)
 #define PRINT_GLOBALREFS() \
-    PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event); \
-    PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+    PrintDebugString("[INFO]:  GlobalRef'd Event: %016I64X"\
+                     "  GlobalRef'd Source: %016I64X", pkg->Event, pkg->AccessibleContextSource);
 #endif
 
 #define FIRE_EVENT(function, packageStruct, packageConstant, eventConstant)             \
     void JavaAccessBridge::function(JNIEnv *env, jobject callingObj,                    \
                                     jobject eventObj, jobject source) {                 \
                                                                                         \
-        PrintDebugString("\r\nFiring event id = %d(%p, %p, %p, %p); vmID = %X",         \
-                         eventConstant, env, callingObj, eventObj, source, javaVM);     \
+        PrintDebugString("[INFO]: Firing event id = %d(%p, %p, %p, %p); vmID = %X",     \
+                        eventConstant, env, callingObj, eventObj, source, dialogWindow);\
                                                                                         \
         /* sanity check */                                                              \
         if (ATs == (AccessBridgeATInstance *) 0) {                                      \
-            PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");           \
+            PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");            \
             return;         /* panic! */                                                \
         }                                                                               \
                                                                                         \
@@ -2513,11 +2497,11 @@
         /* make new Global Refs, send events only to those ATs that want 'em */         \
         AccessBridgeATInstance *ati = ATs;                                              \
         while (ati != (AccessBridgeATInstance *) 0) {                                   \
-            PrintDebugString("\r\njavaEventMask = %X eventConstant=%d pkg->vmID=%X",    \
+            PrintDebugString("[INFO]: javaEventMask = %X eventConstant=%d pkg->vmID=%X",\
                              ati->javaEventMask, eventConstant, pkg->vmID );            \
             if (ati->javaEventMask & eventConstant) {                                   \
                                                                                         \
-                PrintDebugString("  sending to AT");                                    \
+                PrintDebugString("[INFO]:   sending to AT");                            \
                 /* make new GlobalRefs for this AT */                                   \
                 pkg->Event = (JOBJECT64)env->NewGlobalRef(eventObj);                    \
                 pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);    \
@@ -2527,17 +2511,17 @@
             }                                                                           \
             ati = ati->nextATInstance;                                                  \
         }                                                                               \
-        PrintDebugString("  done with firing AWT event");                               \
+        PrintDebugString("[INFO]:   done with firing AWT event");                       \
     }
 
     void JavaAccessBridge::javaShutdown(JNIEnv *env, jobject callingObj) {
 
-        PrintDebugString("\r\nFiring event id = %d(%p, %p); vmID = %X",
-                         cJavaShutdownEvent, env, callingObj, javaVM);
+        PrintDebugString("[INFO]: Firing event id = %d(%p, %p); vmID = %X",
+                         cJavaShutdownEvent, env, callingObj, dialogWindow);
 
         /* sanity check */
         if (ATs == (AccessBridgeATInstance *) 0) {
-            PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+            PrintDebugString("[ERROR]: ATs == 0! (shouldn't happen here!)");
             return;             /* panic! */
         }
 
@@ -2552,12 +2536,12 @@
         AccessBridgeATInstance *ati = ATs;
         while (ati != (AccessBridgeATInstance *) 0) {
             if (ati->javaEventMask & cJavaShutdownEvent) {
-                PrintDebugString("  sending to AT");
+                PrintDebugString("[INFO]:   sending to AT");
                 ati->sendJavaEventPackage(buffer, sizeof(buffer), cJavaShutdownEvent);
             }
             ati = ati->nextATInstance;
         }
-        PrintDebugString("  done with firing AWT event");
+        PrintDebugString("[INFO]:   done with firing AWT event");
     }
 
     FIRE_EVENT(fireFocusGained, FocusGainedPackage, cFocusGainedPackage, cFocusGainedEvent)
diff --git a/src/windows/native/sun/bridge/JavaAccessBridge.h b/src/windows/native/sun/bridge/JavaAccessBridge.h
index d03960f..9340f81 100644
--- a/src/windows/native/sun/bridge/JavaAccessBridge.h
+++ b/src/windows/native/sun/bridge/JavaAccessBridge.h
@@ -44,7 +44,7 @@
                             LPVOID lpvReserved);
         void AppendToCallOutput(char *s);
         BOOL APIENTRY AccessBridgeDialogProc(HWND hDlg, UINT message,
-                                             UINT wParam, LONG lParam);
+                                             WPARAM wParam, LPARAM lParam);
 }
 
 /**
diff --git a/src/windows/native/sun/bridge/WinAccessBridge.cpp b/src/windows/native/sun/bridge/WinAccessBridge.cpp
index ea11414..d5c0b88 100644
--- a/src/windows/native/sun/bridge/WinAccessBridge.cpp
+++ b/src/windows/native/sun/bridge/WinAccessBridge.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -76,7 +76,7 @@
 
             // Remind user later that a new JVM was installed
         case cRemindThereIsNewJVM:
-            PrintDebugString("    newJVMDialogProc: cRemindThereIsNewJVM");
+            PrintDebugString("[INFO]:    newJVMDialogProc: cRemindThereIsNewJVM");
             // do nothing
             EndDialog(hwndDlg, wParam);
             return TRUE;
@@ -130,13 +130,14 @@
 
         switch (fdwReason) {
         case DLL_PROCESS_ATTACH:        // A Windows executable loaded us
-            PrintDebugString("DLL_PROCESS_ATTACH");
+            initializeFileLogger("windows_access_bridge");
+            PrintDebugString("[INFO]: DLL_PROCESS_ATTACH");
             theWindowsAccessBridge = new WinAccessBridge(hinstDll);
             break;
 
         case DLL_PROCESS_DETACH:        // A Windows executable unloaded us
             if (theWindowsAccessBridge != (WinAccessBridge *) 0) {
-                PrintDebugString("*** AccessBridgeDialogProc -> deleting theWindowsAccessBridge");
+                PrintDebugString("[INFO]: *** AccessBridgeDialogProc -> deleting theWindowsAccessBridge");
                 delete theWindowsAccessBridge;
             }
             break;
@@ -173,15 +174,15 @@
 
         switch (message) {
         case WM_INITDIALOG:
-            PrintDebugString("AccessBridgeDialogProc -> Initializing");
+            PrintDebugString("[INFO]: AccessBridgeDialogProc -> Initializing");
             break;
 
             // call from Java with data for us to deliver
         case WM_COPYDATA:
             if (theDialogWindow == (HWND) wParam) {
-                PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL");
+                PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL");
             } else {
-                PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam);
+                PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam);
                 sentToUs = (COPYDATASTRUCT *) lParam;
                 package = (char *) sentToUs->lpData;
                 theWindowsAccessBridge->preProcessPackage(package, sentToUs->cbData);
@@ -190,7 +191,7 @@
 
             // message to ourselves -> de-queue messages and send 'em
         case AB_MESSAGE_QUEUED:
-            PrintDebugString("AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves");
+            PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves");
             theWindowsAccessBridge->receiveAQueuedPackage();
             break;
 
@@ -214,12 +215,12 @@
             // to the message queue.  That would delay the destruction of the instance
             // until the chain is not being traversed.
         case AB_DLL_GOING_AWAY:
-            PrintDebugString("***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message");
+            PrintDebugString("[INFO]: ***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message");
             if (isVMInstanceChainInUse) {
-                PrintDebugString("  javaVMs chain in use, calling PostMessage");
+                PrintDebugString("[INFO]:   javaVMs chain in use, calling PostMessage");
                 PostMessage(hDlg, AB_DLL_GOING_AWAY, wParam, (LPARAM)0);
             } else {
-                PrintDebugString("  calling javaVMDestroyed");
+                PrintDebugString("[INFO]:   calling javaVMDestroyed");
                 theWindowsAccessBridge->JavaVMDestroyed((HWND) wParam);
             }
             break;
@@ -228,7 +229,7 @@
             // the JavaVM is saying "hi"!
             // wParam == sourceHwnd; lParam == JavaVMID
             if (message == theFromJavaHelloMsgID) {
-                PrintDebugString("AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam);
+                PrintDebugString("[INFO]: AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam);
                 theWindowsAccessBridge->rendezvousWithNewJavaDLL((HWND) wParam, (long ) lParam);
             }
             break;
@@ -250,7 +251,7 @@
  */
 WinAccessBridge::WinAccessBridge(HINSTANCE hInstance) {
 
-    PrintDebugString("WinAccessBridge ctor");
+    PrintDebugString("[INFO]: WinAccessBridge ctor");
 
     //  IntializeCriticalSection should only be called once.
     InitializeCriticalSection(&sendMemoryIPCLock);
@@ -276,25 +277,25 @@
     //  -> shut down all event listening
     //  -> release all objects held in the JVM by us
 
-    PrintDebugString("*****in WinAccessBridge::~WinAccessBridge()");
+    PrintDebugString("[INFO]: *****in WinAccessBridge::~WinAccessBridge()");
 
     // send a broadcast msg.; let other AccessBridge DLLs know we're going away
     AccessBridgeJavaVMInstance *current = javaVMs;
     while (current != (AccessBridgeJavaVMInstance *) 0) {
-        PrintDebugString("  telling %p we're going away", current->javaAccessBridgeWindow);
+        PrintDebugString("[INFO]:   telling %p we're going away", current->javaAccessBridgeWindow);
         SendMessage(current->javaAccessBridgeWindow,
                     AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0);
         current = current->nextJVMInstance;
     }
 
-    PrintDebugString("  finished telling JVMs about our demise");
+    PrintDebugString("[INFO]:   finished telling JVMs about our demise");
 
     delete eventHandler;
     delete messageQueue;
     delete javaVMs;
 
-    PrintDebugString("  finished deleting eventHandler, messageQueue, and javaVMs");
-    PrintDebugString("GOODBYE CRUEL WORLD...");
+    PrintDebugString("[INFO]:   finished deleting eventHandler, messageQueue, and javaVMs");
+    PrintDebugString("[INFO]: GOODBYE CRUEL WORLD...");
 
     DestroyWindow(theDialogWindow);
 }
@@ -338,7 +339,7 @@
 WinAccessBridge::rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID) {
     LRESULT returnVal;
 
-    PrintDebugString("in JavaAccessBridge::rendezvousWithNewJavaDLL(%p, %X)",
+    PrintDebugString("[INFO]: in WinAccessBridge::rendezvousWithNewJavaDLL(%p, %X)",
                      JavaBridgeDLLwindow, vmID);
 
     isVMInstanceChainInUse = true;
@@ -354,23 +355,23 @@
         long javaEventMask = eventHandler->getJavaEventMask();
         long accessibilityEventMask = eventHandler->getAccessibilityEventMask();
 
-        PrintDebugString("  Setting Java event mask to: %X", javaEventMask);
+        PrintDebugString("[INFO]:   Setting Java event mask to: %X", javaEventMask);
 
         if (javaEventMask != 0) {
             addJavaEventNotification(javaEventMask);
         }
 
-        PrintDebugString("  Setting Accessibility event mask to: %X", accessibilityEventMask);
+        PrintDebugString("[INFO]:   Setting Accessibility event mask to: %X", accessibilityEventMask);
 
         if (accessibilityEventMask != 0) {
             addAccessibilityEventNotification(accessibilityEventMask);
         }
     } else {
-        PrintDebugString("  ERROR: Failed to initiate IPC with newly created JavaVM!!!");
+        PrintDebugString("[ERROR]: Failed to initiate IPC with newly created JavaVM!!!");
         return FALSE;
     }
 
-    PrintDebugString("  Success!!  We rendezvoused with the JavaDLL");
+    PrintDebugString("[INFO]:   Success!!  We rendezvoused with the JavaDLL");
     return returnVal;
 }
 
@@ -421,7 +422,7 @@
             return FALSE;
         }
     } else {
-        PrintDebugString("ERROR sending memory package: couldn't find destWindow");
+        PrintDebugString("[ERROR]: sending memory package: couldn't find destWindow");
         return FALSE;
     }
     return TRUE;
@@ -434,7 +435,7 @@
  */
 BOOL
 WinAccessBridge::queuePackage(char *buffer, long bufsize) {
-    PrintDebugString("  in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize);
+    PrintDebugString("[INFO]:  in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize);
 
     AccessBridgeQueueElement *element = new AccessBridgeQueueElement(buffer, bufsize);
 
@@ -454,37 +455,37 @@
 WinAccessBridge::receiveAQueuedPackage() {
     AccessBridgeQueueElement *element = NULL;
 
-    PrintDebugString("in WinAccessBridge::receiveAQueuedPackage()");
+    PrintDebugString("[INFO]: in WinAccessBridge::receiveAQueuedPackage()");
 
     // ensure against re-entrancy problems...
     if (messageQueue->getRemoveLockSetting() == FALSE) {
         messageQueue->setRemoveLock(TRUE);
 
-        PrintDebugString("  dequeueing message");
+        PrintDebugString("[INFO]:  dequeueing message");
 
         QueueReturns result = messageQueue->remove(&element);
 
         switch (result) {
 
         case cQueueBroken:
-            PrintDebugString("  ERROR!!! Queue seems to be broken!");
+            PrintDebugString("[ERROR]: Queue seems to be broken!");
             messageQueue->setRemoveLock(FALSE);
             return FALSE;
 
         case cMoreMessages:
         case cQueueEmpty:
             if (element != (AccessBridgeQueueElement *) 0) {
-                PrintDebugString("  found one; sending it!");
+                PrintDebugString("[INFO]:  found one; sending it!");
                 processPackage(element->buffer, element->bufsize);
                 delete element;
             } else {
-                PrintDebugString("  ODD... element == 0!");
+                PrintDebugString("[WARN]:   ODD... element == 0!");
                 return FALSE;
             }
             break;
 
         case cQueueInUse:
-            PrintDebugString("  Queue in use, will try again later...");
+            PrintDebugString("[WARN]:  Queue in use, will try again later...");
             PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0);
             break;
 
@@ -493,7 +494,7 @@
             return FALSE;       // should never get something we don't recognize!
         }
     } else {
-        PrintDebugString("  unable to dequeue message; remove lock is set");
+        PrintDebugString("[WARN]:  unable to dequeue message; remove lock is set");
         PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); // Fix for 6995891
     }
 
@@ -510,13 +511,13 @@
  */
 void
 WinAccessBridge::preProcessPackage(char *buffer, long bufsize) {
-    PrintDebugString("PreProcessing package sent from Java:");
+    PrintDebugString("[INFO]: PreProcessing package sent from Java:");
 
     PackageType *type = (PackageType *) buffer;
 
     switch (*type) {
 
-    PrintDebugString("   type == %X", *type);
+    PrintDebugString("[INFO]:    type == %X", *type);
 
     // event packages all get queued for later handling
     //case cPropertyChangePackage:
@@ -555,11 +556,11 @@
         // perhaps there will be some other packages to process at some point... //
 
     default:
-        PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
+        PrintDebugString("[ERROR]:   processing FAILED!! -> don't know how to handle type = %X", *type);
         break;
     }
 
-    PrintDebugString("   package preprocessing completed");
+    PrintDebugString("[INFO]:    package preprocessing completed");
 }
 
 
@@ -568,12 +569,12 @@
         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
             eventPackage *pkg =                                                     \
                 (eventPackage *) (buffer + sizeof(PackageType));                    \
-            PrintDebugString("   begin callback to AT, type == %X", *type);         \
+            PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
                 theWindowsAccessBridge->eventHandler->fireEventMethod(              \
                     pkg->vmID, pkg->Event, pkg->AccessibleContextSource);           \
-                PrintDebugString("   event callback complete!");                    \
+                PrintDebugString("[INFO]:    event callback complete!");                    \
         } else {                                                                    \
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d", \
+            PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d", \
                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
         }                                                                           \
         break;
@@ -583,13 +584,13 @@
         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
             eventPackage *pkg =                                                     \
                 (eventPackage *) (buffer + sizeof(PackageType));                    \
-            PrintDebugString("   begin callback to AT, type == %X", *type);         \
+            PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
                 pkg->oldValue, pkg->newValue);                                      \
-            PrintDebugString("   event callback complete!");                        \
+            PrintDebugString("[INFO]:    event callback complete!");                        \
         } else {                                                                    \
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d", \
+            PrintDebugString("[ERROR]:   processing FAILED!! -> bufsize = %d; expectation = %d", \
                 bufsize, sizeof(PackageType) + sizeof(eventPackage));               \
         }                                                                           \
         break;
@@ -599,13 +600,13 @@
         if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) {                \
             eventPackage *pkg =                                                     \
                 (eventPackage *) (buffer + sizeof(PackageType));                    \
-            PrintDebugString("   begin callback to AT, type == %X", *type);         \
+            PrintDebugString("[INFO]:    begin callback to AT, type == %X", *type);         \
             theWindowsAccessBridge->eventHandler->fireEventMethod(                  \
                 pkg->vmID, pkg->Event, pkg->AccessibleContextSource,                \
                 pkg->oldValue, pkg->newValue);                                      \
-            PrintDebugString("   event callback complete!");                        \
+            PrintDebugString("[INFO]:    event callback complete!");                        \
         } else {                                                                    \
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d", \
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d", \
                 bufsize, sizeof(PackageType) + sizeof(eventPackage));                \
         }                                                                            \
         break;
@@ -617,24 +618,24 @@
  */
 void
 WinAccessBridge::processPackage(char *buffer, long bufsize) {
-    PrintDebugString("WinAccessBridge::Processing package sent from Java:");
+    PrintDebugString("[INFO]: WinAccessBridge::Processing package sent from Java:");
 
     PackageType *type = (PackageType *) buffer;
 
     switch (*type) {
 
-    PrintDebugString("   type == %X", *type);
+    PrintDebugString("[INFO]:    type == %X", *type);
 
     case cJavaShutdownPackage:
-        PrintDebugString("   type == cJavaShutdownPackage");
+        PrintDebugString("[INFO]:    type == cJavaShutdownPackage");
         if (bufsize == sizeof(PackageType) + sizeof(JavaShutdownPackage)) {
             JavaShutdownPackage *pkg =
                 (JavaShutdownPackage *) (buffer + sizeof(PackageType));
             theWindowsAccessBridge->eventHandler->fireJavaShutdown(pkg->vmID);
-            PrintDebugString("   event callback complete!");
-            PrintDebugString("   event fired!");
+            PrintDebugString("[INFO]:    event callback complete!");
+            PrintDebugString("[INFO]:    event fired!");
         } else {
-            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+            PrintDebugString("[ERROR]:    processing FAILED!! -> bufsize = %d; expectation = %d",
                              bufsize, sizeof(PackageType) + sizeof(JavaShutdownPackage));
         }
         break;
@@ -698,11 +699,11 @@
 
 
             default:
-        PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
+        PrintDebugString("[ERROR]:    processing FAILED!! -> don't know how to handle type = %X", *type);
         break;
     }
 
-    PrintDebugString("   package processing completed");
+    PrintDebugString("[INFO]:    package processing completed");
 }
 
 
@@ -710,7 +711,7 @@
 
 void
 WinAccessBridge::JavaVMDestroyed(HWND VMBridgeDLLWindow) {
-    PrintDebugString("***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow);
+    PrintDebugString("[INFO]: ***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow);
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
         return;
@@ -723,7 +724,7 @@
         javaVMs = javaVMs->nextJVMInstance;
         delete currentVM;
 
-        PrintDebugString("  data structures successfully removed");
+        PrintDebugString("[INFO]:   data structures successfully removed");
 
         // [[[FIXME]]] inform Windows AT that a JVM went away,
         // and that any jobjects it's got lying around for that JVM
@@ -735,7 +736,7 @@
                 previousVM->nextJVMInstance = currentVM->nextJVMInstance;
                 delete currentVM;
 
-                PrintDebugString("  data structures successfully removed");
+                PrintDebugString("[INFO]:   data structures successfully removed");
 
                 // [[[FIXME]]] inform Windows AT that a JVM went away,
                 // and that any jobjects it's got lying around for that JVM
@@ -747,7 +748,7 @@
                 currentVM = currentVM->nextJVMInstance;
             }
         }
-        PrintDebugString("  ERROR!! couldn't find matching data structures!");
+        PrintDebugString("[ERROR]: couldn't find matching data structures!");
     }
     isVMInstanceChainInUse = false;
 }
@@ -765,9 +766,9 @@
 void
 WinAccessBridge::releaseJavaObject(long vmID, JOBJECT64 object) {
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object);
+    PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object);
+    PrintDebugString("[INFO]: WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object);
 #endif
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
         return;
@@ -802,15 +803,16 @@
     *type = cGetAccessBridgeVersionPackage;
     pkg->vmID = vmID;
 
-    PrintDebugString("WinAccessBridge::getVersionInfo(%X, )", vmID);
+    PrintDebugString("[INFO]: WinAccessBridge::getVersionInfo(%X, )", vmID);
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(info, &(pkg->rVersionInfo), sizeof(AccessBridgeVersionInfo));
-            PrintDebugString("  VMversion: %ls", info->VMversion);
-            PrintDebugString("  bridgeJavaClassVersion: %ls", info->bridgeJavaClassVersion);
-            PrintDebugString("  bridgeJavaDLLVersion: %ls", info->bridgeJavaDLLVersion);
-            PrintDebugString("  bridgeWinDLLVersion: %ls", info->bridgeWinDLLVersion);
+            PrintDebugString("[INFO]:   VMversion: %ls\n"\
+                             "          bridgeJavaClassVersion: %ls\n"\
+                             "          bridgeJavaDLLVersion: %ls\n"\
+                             "          bridgeWinDLLVersion: %ls\n"\
+            , info->VMversion, info->bridgeJavaClassVersion, info->bridgeJavaDLLVersion, info->bridgeWinDLLVersion);
             return TRUE;
         }
     }
@@ -843,7 +845,7 @@
         return FALSE;
     }
 
-    PrintDebugString("  in WinAccessBridge::isJavaWindow");
+    PrintDebugString("[INFO]: In WinAccessBridge::isJavaWindow");
 
 
 
@@ -853,7 +855,7 @@
     *type = cIsJavaWindowPackage;
     pkg->window = (jint) window;
 
-    PrintDebugString("WinAccessBridge::isJavaWindow(%p)", window);
+    PrintDebugString("[INFO]: WinAccessBridge::isJavaWindow(%p)", window);
 
     isVMInstanceChainInUse = true;
     AccessBridgeJavaVMInstance *current = javaVMs;
@@ -908,9 +910,9 @@
 WinAccessBridge::isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::isSameObject(%p %p)", obj1, obj2);
+    PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%p %p)", obj1, obj2);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2);
+    PrintDebugString("[INFO]: WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -928,14 +930,14 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
         if (pkg->rResult != 0) {
-            PrintDebugString("  WinAccessBridge::isSameObject returning TRUE (same object)");
+            PrintDebugString("[INFO]:   WinAccessBridge::isSameObject returning TRUE (same object)");
             return TRUE;
         } else {
-            PrintDebugString("  WinAccessBridge::isSameObject returning FALSE (different object)");
+            PrintDebugString("[INFO]:   WinAccessBridge::isSameObject returning FALSE (different object)");
             return FALSE;
         }
     }
-    PrintDebugString("  WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)");
+    PrintDebugString("[ERROR]:   WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)");
     return FALSE;
 }
 
@@ -958,7 +960,7 @@
     *type = cGetAccessibleContextFromHWNDPackage;
     pkg->window = (jint) window;
 
-    PrintDebugString("WinAccessBridge::getAccessibleContextFromHWND(%p, )", window);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextFromHWND(%p, )", window);
 
     DEBUG_CODE(pkg->rVMID = (long ) 0x01010101);
     DEBUG_CODE(pkg->rAccessibleContext = (JOBJECT64) 0x01010101);
@@ -971,15 +973,14 @@
             if (pkg->rAccessibleContext != 0) {
                 *vmID = pkg->rVMID;
                 *AccessibleContext = (JOBJECT64)pkg->rAccessibleContext;
-                PrintDebugString("    current->vmID = %X", current->vmID);
-                PrintDebugString("    pkg->rVMID = %X", pkg->rVMID);
+                PrintDebugString("[INFO]:     current->vmID = %X, pkg->rVMID = %X", current->vmID, pkg->rVMID);
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-                PrintDebugString("    pkg->rAccessibleContext = %p", pkg->rAccessibleContext);
+                PrintDebugString("[INFO]:     pkg->rAccessibleContext = %p", pkg->rAccessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-                PrintDebugString("    pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext);
+                PrintDebugString("[INFO]:     pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext);
 #endif
                 if (pkg->rVMID != current->vmID) {
-                    PrintDebugString("    ERROR! getAccessibleContextFromHWND vmIDs don't match!");
+                    PrintDebugString("[ERROR]: getAccessibleContextFromHWND vmIDs don't match!");
                     isVMInstanceChainInUse = false;
                     return FALSE;
                 }
@@ -994,7 +995,7 @@
     // This isn't really an error; it just means that the HWND was for a non-Java
     // window.  It's also possible the HWND was for a Java window but the JVM has
     // since been shut down and sendMemoryPackage returned FALSE.
-    PrintDebugString("    ERROR! getAccessibleContextFromHWND no matching HWND found!");
+    PrintDebugString("[ERROR]: getAccessibleContextFromHWND no matching HWND found!");
     return FALSE;
 }
 
@@ -1003,7 +1004,7 @@
  */
 HWND
 WinAccessBridge::getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) {
-    PrintDebugString("  in WinAccessBridge::getHWNDFromAccessibleContext");
+    PrintDebugString("[INFO]:   in WinAccessBridge::getHWNDFromAccessibleContext");
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
         return (HWND)0;
     }
@@ -1015,9 +1016,9 @@
     pkg->accessibleContext = accessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext);
 #endif
 
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -1081,7 +1082,7 @@
     pkg->x = x;
     pkg->y = y;
 
-    PrintDebugString("WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y);
     HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID);
     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
         *AccessibleContext = pkg->rAccessibleContext;
@@ -1114,7 +1115,7 @@
     GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
     *type = cGetAccessibleContextWithFocusPackage;
 
-    PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
     // find vmID, etc. from HWND; ask that VM for the AC w/Focus
     HWND pkgVMID;
     if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
@@ -1151,21 +1152,22 @@
     pkg->AccessibleContext = accessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(info, &(pkg->rAccessibleContextInfo), sizeof(AccessibleContextInfo));
-            PrintDebugString("  name: %ls", info->name);
-            PrintDebugString("  description: %ls", info->description);
-            PrintDebugString("  role: %ls", info->role);
-            PrintDebugString("  role_en_US: %ls", info->role_en_US);
-            PrintDebugString("  states: %ls", info->states);
-            PrintDebugString("  states_en_US: %ls", info->states_en_US);
+            PrintDebugString("[INFO]:   name: %ls\n"\
+                             "          description: %ls\n"\
+                             "          role: %ls\n"\
+                             "          role_en_US: %ls\n"\
+                             "          states: %ls\n"\
+                             "          states_en_US: %ls\n"\
+            , info->name, info->description, info->role, info->role_en_US, info->states, info->states_en_US);
             return TRUE;
         }
     }
@@ -1200,9 +1202,9 @@
     pkg->childIndex = childIndex;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -1235,7 +1237,7 @@
     pkg->vmID = vmID;
     pkg->AccessibleContext = AccessibleContext;
 
-    PrintDebugString("WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext);
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
@@ -1255,10 +1257,10 @@
                                         AccessibleTableInfo *tableInfo) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext,
                      tableInfo);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext,
                      tableInfo);
 #endif
 
@@ -1278,12 +1280,12 @@
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
             if (pkg->rTableInfo.rowCount != -1) {
-                PrintDebugString("  ##### WinAccessBridge::getAccessibleTableInfo succeeded");
+                PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableInfo succeeded");
                 return TRUE;
             }
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableInfo failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableInfo failed");
     return FALSE;
 }
 
@@ -1292,7 +1294,7 @@
                                             jint row, jint column,
                                             AccessibleTableCellInfo *tableCellInfo) {
 
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID,
                      accessibleTable, row, column, tableCellInfo);
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1311,13 +1313,13 @@
 
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext);
+            PrintDebugString("[INFO]:   XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext);
             memcpy(tableCellInfo, &(pkg->rTableCellInfo), sizeof(AccessibleTableCellInfo));
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableCellInfo succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableCellInfo succeeded");
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableCellInfo failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableCellInfo failed");
     return FALSE;
 }
 
@@ -1326,9 +1328,9 @@
 WinAccessBridge::getAccessibleTableRowHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1345,12 +1347,12 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowHeader succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowHeader succeeded");
             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowHeader failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowHeader failed");
     return FALSE;
 }
 
@@ -1358,9 +1360,9 @@
 WinAccessBridge::getAccessibleTableColumnHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1377,12 +1379,12 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded");
             memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo));
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnHeader failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnHeader failed");
     return FALSE;
 }
 
@@ -1392,10 +1394,10 @@
                                                   jint row) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext,
                      row);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext,
                      row);
 #endif
 
@@ -1414,11 +1416,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowDescription succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowDescription succeeded");
             return pkg->rAccessibleContext;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowDescription failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowDescription failed");
     return (JOBJECT64)0;
 }
 
@@ -1428,10 +1430,10 @@
                                                      jint column) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext,
                      column);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext,
                      column);
 #endif
 
@@ -1451,11 +1453,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded");
             return pkg->rAccessibleContext;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnDescription failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnDescription failed");
     return (JOBJECT64)0;
 }
 
@@ -1463,9 +1465,9 @@
 WinAccessBridge::getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1483,11 +1485,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded");
             return pkg->rCount;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed");
     return 0;
 }
 
@@ -1495,9 +1497,9 @@
 WinAccessBridge::isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1515,11 +1517,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::isAccessibleTableRowSelected succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::isAccessibleTableRowSelected succeeded");
             return pkg->rResult;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::isAccessibleTableRowSelected failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::isAccessibleTableRowSelected failed");
     return FALSE;
 }
 
@@ -1527,9 +1529,9 @@
 WinAccessBridge::getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1548,12 +1550,12 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelections succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRowSelections succeeded");
             memcpy(selections, pkg->rSelections, count * sizeof(jint));
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRowSelections failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRowSelections failed");
     return FALSE;
 }
 
@@ -1562,10 +1564,10 @@
 WinAccessBridge::getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID,
                      accessibleTable);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID,
                      accessibleTable);
 #endif
 
@@ -1584,20 +1586,20 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded");
             return pkg->rCount;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed");
     return 0;
 }
 
 BOOL
 WinAccessBridge::isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) {
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1615,11 +1617,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded");
             return pkg->rResult;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::isAccessibleTableColumnSelected failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::isAccessibleTableColumnSelected failed");
     return FALSE;
 }
 
@@ -1628,9 +1630,9 @@
                                                     jint *selections) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable);
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable);
+    PrintDebugString("[ERROR]: ##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable);
 #endif
 
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
@@ -1649,12 +1651,12 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded");
             memcpy(selections, pkg->rSelections, count * sizeof(jint));
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumnSelections failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumnSelections failed");
     return FALSE;
 }
 
@@ -1662,10 +1664,10 @@
 WinAccessBridge::getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID,
                      accessibleTable, index);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID,
                      accessibleTable, index);
 #endif
 
@@ -1685,11 +1687,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRow succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableRow succeeded");
             return pkg->rRow;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableRow failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableRow failed");
     return 0;
 }
 
@@ -1697,10 +1699,10 @@
 WinAccessBridge::getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID,
                      accessibleTable, index);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID,
                      accessibleTable, index);
 #endif
 
@@ -1720,11 +1722,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumn succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableColumn succeeded");
             return pkg->rColumn;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableColumn failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableColumn failed");
     return 0;
 }
 
@@ -1732,10 +1734,10 @@
 WinAccessBridge::getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID,
                      accessibleTable, row, column);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID,
                      accessibleTable, row, column);
 #endif
 
@@ -1756,11 +1758,11 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleTableIndex succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleTableIndex succeeded");
             return pkg->rIndex;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleTableIndex failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleTableIndex failed");
     return 0;
 }
 
@@ -1771,10 +1773,10 @@
                                           AccessibleRelationSetInfo *relationSetInfo) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID,
                      accessibleContext, relationSetInfo);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID,
                      accessibleContext, relationSetInfo);
 #endif
 
@@ -1792,14 +1794,14 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### pkg->rAccessibleRelationSetInfo.relationCount = %X",
+            PrintDebugString("[INFO]:   ##### pkg->rAccessibleRelationSetInfo.relationCount = %X",
                              pkg->rAccessibleRelationSetInfo.relationCount);
             memcpy(relationSetInfo, &(pkg->rAccessibleRelationSetInfo), sizeof(AccessibleRelationSetInfo));
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleRelationSet succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleRelationSet succeeded");
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleRelationSet failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleRelationSet failed");
     return FALSE;
 }
 
@@ -1811,10 +1813,10 @@
                                         AccessibleHypertextInfo *hypertextInfo) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID,
                      accessibleContext, hypertextInfo);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID,
                      accessibleContext, hypertextInfo);
 #endif
 
@@ -1834,13 +1836,13 @@
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
 
-            PrintDebugString("  ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext succeeded");
+            PrintDebugString("[INFO]:   ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertext succeeded");
 
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertext failed");
     return FALSE;
 }
 
@@ -1850,10 +1852,10 @@
                                              JOBJECT64 accessibleHyperlink) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext,
+    PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext,
                      accessibleHyperlink);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext,
+    PrintDebugString("[INFO]: WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext,
                      accessibleHyperlink);
 #endif
 
@@ -1873,7 +1875,7 @@
     if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
         return pkg->rResult;
     }
-    PrintDebugString("  WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)");
+    PrintDebugString("[ERROR]:  WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)");
     return FALSE;
 }
 
@@ -1887,10 +1889,10 @@
                                              const AccessibleContext accessibleContext) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)",
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)",
                      vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)",
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)",
                      vmID, accessibleContext);
 #endif
 
@@ -1908,12 +1910,12 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### hypetext link count = %d", pkg->rLinkCount);
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded");
+            PrintDebugString("[INFO]:   ##### hypetext link count = %d", pkg->rLinkCount);
+            PrintDebugString("[INFO]:  ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded");
             return pkg->rLinkCount;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleHyperlinkCount failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHyperlinkCount failed");
     return -1;
 }
 
@@ -1931,10 +1933,10 @@
                                            /* OUT */ AccessibleHypertextInfo *hypertextInfo) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID,
                      accessibleContext, hypertextInfo);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID,
                      accessibleContext, hypertextInfo);
 #endif
 
@@ -1953,19 +1955,18 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### pkg->rSuccess = %d", pkg->rSuccess);
+            PrintDebugString("[INFO]:   ##### pkg->rSuccess = %d", pkg->rSuccess);
 
             memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo));
             if (pkg->rSuccess == TRUE) {
-                PrintDebugString("  ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
-                PrintDebugString("  ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
+                PrintDebugString("[INFO]:   ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount);
             } else {
-                PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextExt failed");
+                PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertextExt failed");
             }
-            return pkg->rSuccess;;
+            return pkg->rSuccess;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextExt failed");
+    PrintDebugString("[ERROR]:  ##### WinAccessBridge::getAccessibleHypertextExt failed");
     return FALSE;
 }
 
@@ -1982,10 +1983,10 @@
                                                  const jint charIndex) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)",
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)",
                      vmID, hypertext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)",
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)",
                      vmID, hypertext);
 #endif
 
@@ -2004,12 +2005,12 @@
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  ##### hypetext link index = %d", pkg->rLinkIndex);
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextLinkIndex  succeeded");
+            PrintDebugString("[INFO]:   ##### hypetext link index = %d", pkg->rLinkIndex);
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertextLinkIndex  succeeded");
             return pkg->rLinkIndex;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertextLinkIndex  failed");
+    PrintDebugString("[ERROR]  ##### WinAccessBridge::getAccessibleHypertextLinkIndex  failed");
     return -1;
 }
 
@@ -2025,10 +2026,10 @@
                                         /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID,
                      hypertext, hyperlinkInfo);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID,
                      hypertext, hyperlinkInfo);
 #endif
 
@@ -2049,11 +2050,11 @@
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(hyperlinkInfo, &(pkg->rAccessibleHyperlinkInfo),
                    sizeof(AccessibleHyperlinkInfo));
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleHypertext succeeded");
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleHypertext failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleHypertext failed");
     return FALSE;
 }
 
@@ -2065,10 +2066,10 @@
                                           AccessibleKeyBindings *keyBindings) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID,
                      accessibleContext, keyBindings);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID,
                      accessibleContext, keyBindings);
 #endif
 
@@ -2088,19 +2089,20 @@
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(keyBindings, &(pkg->rAccessibleKeyBindings), sizeof(AccessibleKeyBindings));
 
-            PrintDebugString("  ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount);
+            PrintDebugString("[INFO]:   ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount);
             for (int i = 0; i < keyBindings->keyBindingsCount; ++i) {
-                PrintDebugString("  Key Binding # %d", i+1);
-                PrintDebugString("    Modifiers: 0x%x", keyBindings->keyBindingInfo[i].modifiers);
-                PrintDebugString("    Character (hex):  0x%x", keyBindings->keyBindingInfo[i].character);
-                PrintDebugString("    Character (wide char):  %lc", keyBindings->keyBindingInfo[i].character);
+                PrintDebugString("[INFO]:   Key Binding # %d"\
+                "                           Modifiers: 0x%x"\
+                "                           Character (hex):  0x%x"\
+                "                           Character (wide char):  %lc"\
+                , i+1, keyBindings->keyBindingInfo[i].modifiers, keyBindings->keyBindingInfo[i].character, keyBindings->keyBindingInfo[i].character);
             }
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleKeyBindings succeeded");
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleKeyBindings succeeded");
 
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleKeyBindings failed");
+    PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleKeyBindings failed");
     return FALSE;
 }
 
@@ -2108,10 +2110,10 @@
 WinAccessBridge::getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID,
                      accessibleContext, icons);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID,
                      accessibleContext, icons);
 #endif
 
@@ -2131,13 +2133,13 @@
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(icons, &(pkg->rAccessibleIcons), sizeof(AccessibleIcons));
 
-            PrintDebugString("  ##### icons.iconsCount = %d", icons->iconsCount);
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleIcons succeeded");
+            PrintDebugString("[INFO]:   ##### icons.iconsCount = %d", icons->iconsCount);
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleIcons succeeded");
 
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleIcons failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleIcons failed");
     return FALSE;
 }
 
@@ -2145,10 +2147,10 @@
 WinAccessBridge::getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID,
                      accessibleContext, actions);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID,
+    PrintDebugString("[INFO]: ##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID,
                      accessibleContext, actions);
 #endif
 
@@ -2168,13 +2170,13 @@
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(actions, &(pkg->rAccessibleActions), sizeof(AccessibleActions));
 
-            PrintDebugString("  ##### actions.actionsCount = %d", actions->actionsCount);
-            PrintDebugString("  ##### WinAccessBridge::getAccessibleActions succeeded");
+            PrintDebugString("[INFO]:   ##### actions.actionsCount = %d", actions->actionsCount);
+            PrintDebugString("[INFO]:   ##### WinAccessBridge::getAccessibleActions succeeded");
 
             return TRUE;
         }
     }
-    PrintDebugString("  ##### WinAccessBridge::getAccessibleActions failed");
+    PrintDebugString("[ERROR]:   ##### WinAccessBridge::getAccessibleActions failed");
     return FALSE;
 }
 
@@ -2183,11 +2185,11 @@
                                      AccessibleActionsToDo *actionsToDo, jint *failure) {
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext,
+    PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext,
                      actionsToDo->actionsCount,
                      actionsToDo->actions[0].name);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext,
+    PrintDebugString("[INFO]: WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext,
                      actionsToDo->actionsCount,
                      actionsToDo->actions[0].name);
 #endif
@@ -2209,7 +2211,7 @@
         *failure = pkg->failure;
         return pkg->rResult;
     }
-    PrintDebugString("  WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)");
+    PrintDebugString("[ERROR]:   WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)");
     return FALSE;
 }
 
@@ -2234,9 +2236,9 @@
     wcsncpy(pkg->text, text, sizeof(pkg->text)/sizeof(wchar_t)); // wide character copy
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text);
+    PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text);
+    PrintDebugString("[INFO]: WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2271,18 +2273,19 @@
     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext);
 #endif
-    PrintDebugString("  pkg->vmID: %X", pkg->vmID);
-    PrintDebugString("  pkg->accessibleContext: %p", pkg->accessibleContext);
-    PrintDebugString("  pkg->role: %ls", pkg->role);
+    PrintDebugString("[INFO]:   pkg->vmID: %X"\
+                     "          pkg->accessibleContext: %p"\
+                     "          pkg->role: %ls"\
+                     , pkg->vmID, pkg->accessibleContext, pkg->role);
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
-            PrintDebugString("  pkg->rAccessibleContext: %p", pkg->rAccessibleContext);
+            PrintDebugString("[INFO]:   pkg->rAccessibleContext: %p", pkg->rAccessibleContext);
             return pkg->rAccessibleContext;
         }
     }
@@ -2310,9 +2313,9 @@
     pkg->accessibleContext = accessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2345,9 +2348,9 @@
     memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role));
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2378,9 +2381,9 @@
     pkg->accessibleContext = accessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2410,9 +2413,9 @@
     pkg->accessibleContext = accessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2451,16 +2454,16 @@
     pkg->len = (int)max;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
     if (destABWindow != (HWND) 0) {
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             wcsncpy(name, pkg->rName, max);
-            PrintDebugString("    WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name);
+            PrintDebugString("[INFO]:     WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name);
             return TRUE;
         }
     }
@@ -2486,9 +2489,9 @@
     pkg->accessibleContext = accessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2521,10 +2524,10 @@
     pkg->endIndex = endIndex;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("    WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]:     WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext,
                      startIndex, endIndex);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("    WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]:     WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext,
                      startIndex, endIndex);
 #endif
     // need to call only the HWND/VM that contains this AC
@@ -2563,10 +2566,10 @@
 
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("    WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]:     WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext,
                      startIndex, endIndex);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("    WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext,
+    PrintDebugString("[INFO]:     WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext,
                      startIndex, endIndex);
 #endif
     // need to call only the HWND/VM that contains this AC
@@ -2600,9 +2603,9 @@
     pkg->accessibleContext = accessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2635,9 +2638,9 @@
     pkg->startIndex = startIndex;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2670,9 +2673,9 @@
     pkg->position = position;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext);
+    PrintDebugString("[INFO]: WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2712,9 +2715,9 @@
     pkg->y = y;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2722,9 +2725,10 @@
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
             memcpy(textInfo, &(pkg->rTextInfo), sizeof(AccessibleTextInfo));
             if (pkg->rTextInfo.charCount != -1) {
-                PrintDebugString("  charCount: %d", textInfo->charCount);
-                PrintDebugString("  caretIndex: %d", textInfo->caretIndex);
-                PrintDebugString("  indexAtPoint: %d", textInfo->indexAtPoint);
+                PrintDebugString("[INFO]:   charCount: %d"\
+                                 "          caretIndex: %d"\
+                                 "          indexAtPoint: %d"\
+                                 , textInfo->charCount, textInfo->caretIndex, textInfo->indexAtPoint);
                 return TRUE;
             }
         }
@@ -2760,9 +2764,9 @@
     pkg->rTextItemsInfo.sentence[0] = '\0';
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2799,9 +2803,9 @@
     pkg->AccessibleContext = AccessibleContext;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2839,9 +2843,9 @@
     pkg->index = index;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2877,9 +2881,9 @@
     pkg->index = index;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2917,9 +2921,9 @@
     pkg->index = index;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -2969,9 +2973,9 @@
     pkg->index = index;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -3011,9 +3015,9 @@
     pkg->end = end;
 
 #ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
-    PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end);
 #else // JOBJECT64 is jlong (64 bit)
-    PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end);
+    PrintDebugString("[INFO]: WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end);
 #endif
     // need to call only the HWND/VM that contains this AC
     HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID);
@@ -3290,7 +3294,7 @@
  */
 void
 WinAccessBridge::addJavaEventNotification(jlong type) {
-    PrintDebugString("WinAccessBridge::addJavaEventNotification(%016I64X)", type);
+    PrintDebugString("[INFO]: WinAccessBridge::addJavaEventNotification(%016I64X)", type);
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
         return;
     }
@@ -3302,7 +3306,7 @@
     pkg->type = type;
     pkg->DLLwindow = ABHandleToLong(dialogWindow);
 
-    PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
+    PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
                      *pkgType, pkg->type, pkg->DLLwindow);
 
     // send addEventNotification message to all JVMs
@@ -3327,7 +3331,7 @@
  */
 void
 WinAccessBridge::removeJavaEventNotification(jlong type) {
-    PrintDebugString("in WinAccessBridge::removeJavaEventNotification(%016I64X)", type);
+    PrintDebugString("[INFO]: in WinAccessBridge::removeJavaEventNotification(%016I64X)", type);
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
         return;
     }
@@ -3338,7 +3342,7 @@
     pkg->type = type;
     pkg->DLLwindow = ABHandleToLong(dialogWindow);
 
-    PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
+    PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %p",
                      *pkgType, pkg->type, pkg->DLLwindow);
 
     // send removeEventNotification message to all JVMs
@@ -3365,7 +3369,7 @@
  */
 void
 WinAccessBridge::addAccessibilityEventNotification(jlong type) {
-    PrintDebugString("in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type);
+    PrintDebugString("[INFO]: in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type);
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
         return;
     }
@@ -3376,7 +3380,7 @@
     pkg->type = type;
     pkg->DLLwindow = ABHandleToLong(dialogWindow);
 
-    PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
+    PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
                      *pkgType, pkg->type, pkg->DLLwindow);
 
     // send addEventNotification message to all JVMs
@@ -3401,7 +3405,7 @@
  */
 void
 WinAccessBridge::removeAccessibilityEventNotification(jlong type) {
-    PrintDebugString("in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type);
+    PrintDebugString("[INFO]: in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type);
     if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) {
         return;
     }
@@ -3412,7 +3416,7 @@
     pkg->type = type;
     pkg->DLLwindow = ABHandleToLong(dialogWindow);
 
-    PrintDebugString("  ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
+    PrintDebugString("[INFO]:   ->pkgType = %X, eventType = %016I64X, DLLwindow = %X",
                      *pkgType, pkg->type, pkg->DLLwindow);
 
     // send removeEventNotification message to all JVMs
diff --git a/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c b/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c
index d316a63..8b948e9 100644
--- a/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c
+++ b/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -58,12 +58,29 @@
 
 JNIEXPORT void JNICALL
 Java_sun_java2d_opengl_WGLSurfaceData_initOps(JNIEnv *env, jobject wglsd,
-                                              jlong pConfigInfo,
+                                              jobject gc, jlong pConfigInfo,
                                               jobject peer, jlong hwnd)
 {
-    OGLSDOps *oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, wglsd,
+    OGLSDOps *oglsdo;
+    WGLSDOps *wglsdo;
+
+    gc = (*env)->NewGlobalRef(env, gc);
+    if (gc == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+        return;
+    }
+
+    oglsdo = (OGLSDOps *)SurfaceData_InitOps(env, wglsd,
                                                        sizeof(OGLSDOps));
-    WGLSDOps *wglsdo = (WGLSDOps *)malloc(sizeof(WGLSDOps));
+    if (oglsdo == NULL) {
+        (*env)->DeleteGlobalRef(env, gc);
+        JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
+        return;
+    }
+    // later the graphicsConfig will be used for deallocation of oglsdo
+    oglsdo->graphicsConfig = gc;
+
+    wglsdo = (WGLSDOps *)malloc(sizeof(WGLSDOps));
 
     J2dTraceLn(J2D_TRACE_INFO, "WGLSurfaceData_initOps");
 
@@ -160,33 +177,6 @@
 }
 
 /**
- * Returns a pointer (as a jlong) to the native WGLGraphicsConfigInfo
- * associated with the given OGLSDOps.  This method can be called from
- * shared code to retrieve the native GraphicsConfig data in a platform-
- * independent manner.
- */
-jlong
-OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
-{
-    WGLSDOps *wglsdo;
-
-    if (oglsdo == NULL) {
-        J2dRlsTraceLn(J2D_TRACE_ERROR,
-                      "OGLSD_GetNativeConfigInfo: ops are null");
-        return 0L;
-    }
-
-    wglsdo = (WGLSDOps *)oglsdo->privOps;
-    if (wglsdo == NULL) {
-        J2dRlsTraceLn(J2D_TRACE_ERROR,
-                      "OGLSD_GetNativeConfigInfo: wgl ops are null");
-        return 0L;
-    }
-
-    return ptr_to_jlong(wglsdo->configInfo);
-}
-
-/**
  * Makes the given GraphicsConfig's context current to its associated
  * "scratch" surface.  If there is a problem making the context current,
  * this method will return NULL; otherwise, returns a pointer to the
diff --git a/src/windows/native/sun/security/krb5/NativeCreds.c b/src/windows/native/sun/security/krb5/NativeCreds.c
index b7f81d2..ec891a9 100644
--- a/src/windows/native/sun/security/krb5/NativeCreds.c
+++ b/src/windows/native/sun/security/krb5/NativeCreds.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -404,6 +404,8 @@
                     "(Lsun/security/krb5/internal/Ticket;"
                     "Lsun/security/krb5/PrincipalName;"
                     "Lsun/security/krb5/PrincipalName;"
+                    "Lsun/security/krb5/PrincipalName;"
+                    "Lsun/security/krb5/PrincipalName;"
                     "Lsun/security/krb5/EncryptionKey;"
                     "Lsun/security/krb5/internal/TicketFlags;"
                     "Lsun/security/krb5/internal/KerberosTime;"
@@ -665,7 +667,9 @@
                 krbcredsConstructor,
                 ticket,
                 clientPrincipal,
+                NULL,
                 targetPrincipal,
+                NULL,
                 encryptionKey,
                 ticketFlags,
                 authTime, // mdu
diff --git a/test/ProblemList.txt b/test/ProblemList.txt
index bb7f700..cc0ce49 100644
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -267,6 +267,9 @@
 
 # 8026976
 sun/security/pkcs11/ec/TestKeyFactory.java                      generic-all
+# 8180837
+sun/security/pkcs11/Secmod/AddTrustedCert.java                  generic-all
+sun/security/pkcs11/tls/TestKeyMaterial.java                    generic-all
 
 # 7164518
 sun/security/krb5/auto/Unreachable.java                         macosx-all
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java b/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
index 8d05806..dbd9723 100644
--- a/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015, Red Hat, Inc.
+ * Copyright (c) 2015, Oracle, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +25,14 @@
 /*
  * @test
  * @bug 8069072
- * @summary Test vectors for com.sun.crypto.provider.GHASH
+ * @summary Test vectors for com.sun.crypto.provider.GHASH.
+ *
+ * Single iteration to verify software-only GHASH algorithm.
+ * @run main TestGHASH
+ *
+ * Multi-iteration to verify test intrinsics GHASH, if available.
+ * Many iterations are needed so we are sure hotspot will use intrinsic
+ * @run main TestGHASH -n 10000
  */
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -124,43 +132,55 @@
 
     public static void main(String[] args) throws Exception {
         TestGHASH test;
-        if (args.length == 0) {
-            test = new TestGHASH("com.sun.crypto.provider.GHASH");
-        } else {
-            test = new TestGHASH(args[0]);
+        String test_class = "com.sun.crypto.provider.GHASH";
+        int i = 0;
+        int num_of_loops = 1;
+        while (args.length > i) {
+            if (args[i].compareTo("-c") == 0) {
+                test_class = args[++i];
+            } else if (args[i].compareTo("-n") == 0) {
+                num_of_loops = Integer.parseInt(args[++i]);
+            }
+            i++;
         }
 
-        // Test vectors from David A. McGrew, John Viega,
-        // "The Galois/Counter Mode of Operation (GCM)", 2005.
-        // <http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf>
+        System.out.println("Running " + num_of_loops + " iterations.");
+        test = new TestGHASH(test_class);
+        i = 0;
 
-        test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "",
-                "00000000000000000000000000000000");
-        test.check(2,
-                "66e94bd4ef8a2c3b884cfa59ca342b2e", "",
-                "0388dace60b6a392f328c2b971b2fe78",
-                "f38cbb1ad69223dcc3457ae5b6b0f885");
-        test.check(3,
-                "b83b533708bf535d0aa6e52980d53b78", "",
-                "42831ec2217774244b7221b784d0d49c" +
-                "e3aa212f2c02a4e035c17e2329aca12e" +
-                "21d514b25466931c7d8f6a5aac84aa05" +
-                "1ba30b396a0aac973d58e091473f5985",
-                "7f1b32b81b820d02614f8895ac1d4eac");
-        test.check(4,
-                "b83b533708bf535d0aa6e52980d53b78",
-                "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
-                "42831ec2217774244b7221b784d0d49c" +
-                "e3aa212f2c02a4e035c17e2329aca12e" +
-                "21d514b25466931c7d8f6a5aac84aa05" +
-                "1ba30b396a0aac973d58e091",
-                "698e57f70e6ecc7fd9463b7260a9ae5f");
-        test.check(5, "b83b533708bf535d0aa6e52980d53b78",
-                "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
-                "61353b4c2806934a777ff51fa22a4755" +
-                "699b2a714fcdc6f83766e5f97b6c7423" +
-                "73806900e49f24b22b097544d4896b42" +
-                "4989b5e1ebac0f07c23f4598",
-                "df586bb4c249b92cb6922877e444d37b");
+        while (num_of_loops > i) {
+            // Test vectors from David A. McGrew, John Viega,
+            // "The Galois/Counter Mode of Operation (GCM)", 2005.
+            // <http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf>
+            test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "",
+                       "00000000000000000000000000000000");
+            test.check(2,
+                       "66e94bd4ef8a2c3b884cfa59ca342b2e", "",
+                       "0388dace60b6a392f328c2b971b2fe78",
+                       "f38cbb1ad69223dcc3457ae5b6b0f885");
+            test.check(3,
+                       "b83b533708bf535d0aa6e52980d53b78", "",
+                       "42831ec2217774244b7221b784d0d49c" +
+                       "e3aa212f2c02a4e035c17e2329aca12e" +
+                       "21d514b25466931c7d8f6a5aac84aa05" +
+                       "1ba30b396a0aac973d58e091473f5985",
+                       "7f1b32b81b820d02614f8895ac1d4eac");
+            test.check(4,
+                       "b83b533708bf535d0aa6e52980d53b78",
+                       "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
+                       "42831ec2217774244b7221b784d0d49c" +
+                       "e3aa212f2c02a4e035c17e2329aca12e" +
+                       "21d514b25466931c7d8f6a5aac84aa05" +
+                       "1ba30b396a0aac973d58e091",
+                       "698e57f70e6ecc7fd9463b7260a9ae5f");
+            test.check(5, "b83b533708bf535d0aa6e52980d53b78",
+                       "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
+                       "61353b4c2806934a777ff51fa22a4755" +
+                       "699b2a714fcdc6f83766e5f97b6c7423" +
+                       "73806900e49f24b22b097544d4896b42" +
+                       "4989b5e1ebac0f07c23f4598",
+                       "df586bb4c249b92cb6922877e444d37b");
+            i++;
+        }
     }
 }
diff --git a/test/com/sun/tools/attach/StartManagementAgent.java b/test/com/sun/tools/attach/StartManagementAgent.java
index da82895..cc39690 100644
--- a/test/com/sun/tools/attach/StartManagementAgent.java
+++ b/test/com/sun/tools/attach/StartManagementAgent.java
@@ -93,7 +93,7 @@
         } catch(AttachOperationFailedException ex) {
             // We expect parsing of "apa" above to fail, but if the file path
             // can't be read we get a different exception message
-            if (!ex.getMessage().contains("Invalid com.sun.management.jmxremote.port number")) {
+            if (!ex.getMessage().contains("NumberFormatException: For input string: \"apa\"")) {
                 throw ex;
             }
         }
diff --git a/test/java/awt/GraphicsDevice/CheckDisplayModes.java b/test/java/awt/GraphicsDevice/CheckDisplayModes.java
index 719ee9b..9fced18 100644
--- a/test/java/awt/GraphicsDevice/CheckDisplayModes.java
+++ b/test/java/awt/GraphicsDevice/CheckDisplayModes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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 8007146
+ * @bug 8007146 8213119
  * @summary [macosx] Setting a display mode crashes JDK under VNC
  * @author Alexander Scherbatiy
  * @run main CheckDisplayModes
@@ -36,27 +36,28 @@
 
     public static void main(String[] args) {
         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
-        GraphicsDevice graphicDevice = ge.getDefaultScreenDevice();
-        if (!graphicDevice.isDisplayChangeSupported()) {
-            System.err.println("Display mode change is not supported on this host. Test is considered passed.");
-            return;
-        }
-        DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode();
-        checkDisplayMode(defaultDisplayMode);
-        graphicDevice.setDisplayMode(defaultDisplayMode);
-
-        DisplayMode[] displayModes = graphicDevice.getDisplayModes();
-        boolean isDefaultDisplayModeIncluded = false;
-        for (DisplayMode displayMode : displayModes) {
-            checkDisplayMode(displayMode);
-            graphicDevice.setDisplayMode(displayMode);
-            if (defaultDisplayMode.equals(displayMode)) {
-                isDefaultDisplayModeIncluded = true;
+        for (GraphicsDevice graphicDevice : ge.getScreenDevices()) {
+            if (!graphicDevice.isDisplayChangeSupported()) {
+                System.err.println("Display mode change is not supported on this host. Test is considered passed.");
+                continue;
             }
-        }
+            DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode();
+            checkDisplayMode(defaultDisplayMode);
+            graphicDevice.setDisplayMode(defaultDisplayMode);
 
-        if (!isDefaultDisplayModeIncluded) {
-            throw new RuntimeException("Default display mode is not included");
+            DisplayMode[] displayModes = graphicDevice.getDisplayModes();
+            boolean isDefaultDisplayModeIncluded = false;
+            for (DisplayMode displayMode : displayModes) {
+                checkDisplayMode(displayMode);
+                graphicDevice.setDisplayMode(displayMode);
+                if (defaultDisplayMode.equals(displayMode)) {
+                    isDefaultDisplayModeIncluded = true;
+                }
+            }
+
+            if (!isDefaultDisplayModeIncluded) {
+                throw new RuntimeException("Default display mode is not included");
+            }
         }
     }
 
diff --git a/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java b/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java
index d0b4031..d30e571 100644
--- a/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java
+++ b/test/java/awt/GraphicsEnvironment/LoadLock/GE_init5.java
@@ -25,10 +25,10 @@
  * @test
  * @bug 7002839
  * @summary Static init deadlock Win32GraphicsEnvironment and WToolkit
- * @run main/othervm -Djava.awt.headless=true GE_init4
+ * @run main/othervm -Djava.awt.headless=true GE_init5
  */
 
-import java.awt.Toolkit;
+import java.awt.GraphicsEnvironment;
 
 public class GE_init5 {
     public static void main(String[] args) {
diff --git a/test/java/awt/font/GlyphVector/GlyphVectorOutline.java b/test/java/awt/font/GlyphVector/GlyphVectorOutline.java
new file mode 100644
index 0000000..5680f7b
--- /dev/null
+++ b/test/java/awt/font/GlyphVector/GlyphVectorOutline.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2014 Google Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.text.AttributedString;
+
+import javax.imageio.ImageIO;
+
+/**
+ * Manual test for:
+ * JDK-8057986: freetype code to get glyph outline does not handle initial control point properly
+ *
+ * Manual repro recipe:
+ * (cd test/java/awt/font/GlyphVector/ && javac GlyphVectorOutline.java && wget -q -O/tmp/msgothic.ttc https://browserlinux-jp.googlecode.com/files/msgothic.ttc && java GlyphVectorOutline /tmp/msgothic.ttc /tmp/katakana.png)
+ *
+ * Then examine the two rendered Japanese characters in the png file.
+ *
+ * Renders text to a PNG by
+ * 1. using the native Graphics2D#drawGlyphVector implementation
+ * 2. filling in the result of GlyphVector#getOutline
+ *
+ * Should be the same but is different for some CJK characters
+ * (e.g. Katakana character \u30AF).
+ *
+ * @author ikopylov@google.com (Igor Kopylov)
+ */
+public class GlyphVectorOutline {
+    public static void main(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Error("Usage: java GlyphVectorOutline fontfile outputfile");
+        }
+        writeImage(new File(args[0]),
+                   new File(args[1]),
+                   "\u30AF");
+    }
+
+    public static void writeImage(File fontFile, File outputFile, String value) throws Exception {
+        BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = image.createGraphics();
+        g.setColor(Color.WHITE);
+        g.fillRect(0, 0, image.getWidth(), image.getHeight());
+        g.setColor(Color.BLACK);
+
+        Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
+        font = font.deriveFont(Font.PLAIN, 72f);
+        FontRenderContext frc = new FontRenderContext(null, false, false);
+        GlyphVector gv = font.createGlyphVector(frc, value);
+        g.drawGlyphVector(gv, 10, 80);
+        g.fill(gv.getOutline(10, 180));
+        ImageIO.write(image, "png", outputFile);
+    }
+
+    private static void drawString(Graphics2D g, Font font, String value, float x, float y) {
+        AttributedString str = new AttributedString(value);
+        str.addAttribute(TextAttribute.FOREGROUND, Color.BLACK);
+        str.addAttribute(TextAttribute.FONT, font);
+        FontRenderContext frc = new FontRenderContext(null, true, true);
+        TextLayout layout = new LineBreakMeasurer(str.getIterator(), frc).nextLayout(Integer.MAX_VALUE);
+        layout.draw(g, x, y);
+    }
+}
diff --git a/test/java/awt/font/Rotate/RotatedFontMetricsTest.java b/test/java/awt/font/Rotate/RotatedFontMetricsTest.java
new file mode 100644
index 0000000..b4d9d2c
--- /dev/null
+++ b/test/java/awt/font/Rotate/RotatedFontMetricsTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, 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    RotatedFontMetricsTest
+ * @bug     8139178
+ * @summary This test verifies that rotation does not affect font metrics.
+ * @run     main RotatedFontMetricsTest
+ */
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+public class RotatedFontMetricsTest {
+    static final int FONT_SIZE = Integer.getInteger("font.size", 20);
+
+    public static void main(String ... args) {
+        Font font = new Font(Font.DIALOG, Font.PLAIN, FONT_SIZE);
+        Graphics2D g2d = createGraphics();
+
+        FontMetrics ref = null;
+        RuntimeException failure = null;
+        for (int a = 0; a < 360; a += 15) {
+            Graphics2D g = (Graphics2D)g2d.create();
+            g.rotate(Math.toRadians(a));
+            FontMetrics m = g.getFontMetrics(font);
+            g.dispose();
+
+            boolean status = true;
+            if (ref == null) {
+                ref = m;
+            } else {
+                status = ref.getAscent() == m.getAscent() &&
+                        ref.getDescent() == m.getDescent() &&
+                        ref.getLeading() == m.getLeading() &&
+                        ref.getMaxAdvance() == m.getMaxAdvance();
+            }
+
+            System.out.printf("Metrics a%d, d%d, l%d, m%d (%d) %s\n",
+                    m.getAscent(), m.getDescent(), m.getLeading(), m.getMaxAdvance(),
+                    (int)a, status ? "OK" : "FAIL");
+
+            if (!status && failure == null) {
+                failure = new RuntimeException("Font metrics differ for angle " + a);
+            }
+        }
+        if (failure != null) {
+            throw failure;
+        }
+        System.out.println("done");
+    }
+
+    private static Graphics2D createGraphics() {
+        BufferedImage dst = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
+        return dst.createGraphics();
+    }
+}
diff --git a/test/java/awt/font/TextLayout/HangulShapingTest.java b/test/java/awt/font/TextLayout/HangulShapingTest.java
new file mode 100644
index 0000000..2febfad
--- /dev/null
+++ b/test/java/awt/font/TextLayout/HangulShapingTest.java
@@ -0,0 +1,72 @@
+// Copyright 2019 Azul Systems, Inc.  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 Azul Systems, 385 Moffett Park Drive, Suite 115, Sunnyvale,
+// CA 94089 USA or visit www.azul.com if you need additional information or
+// have any questions.
+
+import java.awt.Font;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+/*
+ * @test
+ * @bug 8215210
+ * @summary Downport of prr's fix to a certain ICU wrong condition breaking some Hangul shaping
+ * @run main/othervm  -Dsun.font.layoutengine=icu HangulShapingTest
+ */
+public class HangulShapingTest {
+    public static void main(String args[]) {
+        if (!System.getProperty("os.name").startsWith("Mac")) {
+            return;
+        }
+
+        // images of the strings as drawn should be identical
+        String beforeString = "\u1100\u1161 \u1102\u1161";
+        String afterString = "\uAC00 \uB098";
+        int w = 100, h = 100;
+
+        BufferedImage bi1 = drawit(w, h, beforeString);
+        BufferedImage bi2 = drawit(w, h, afterString);
+
+        boolean same = true;
+        for (int x = 0; x < w; x++) {
+            for (int y = 0; y < h; y++) {
+                int c1 = bi1.getRGB(x, y);
+                int c2 = bi2.getRGB(x, y);
+                same &= (c1 == c2);
+            }
+            if (!same) {
+               break;
+            }
+        }
+        if (!same) {
+            throw new RuntimeException("Images differ");
+        }
+    }
+    private static BufferedImage drawit(int w, int h, String toDraw) {
+        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+        Graphics2D biGraphics = bi.createGraphics();
+        biGraphics.setColor(Color.white);
+        biGraphics.fillRect(0, 0, w, h);
+        biGraphics.setColor(Color.black);
+        Font font = new Font("Dialog", Font.PLAIN, 20);
+        biGraphics.setFont(font);
+        biGraphics.drawString(toDraw, 10, 40);
+        return bi;
+    }
+}
diff --git a/test/java/awt/font/TextLayout/HebrewIsRTLTest.java b/test/java/awt/font/TextLayout/HebrewIsRTLTest.java
new file mode 100644
index 0000000..1ced41d
--- /dev/null
+++ b/test/java/awt/font/TextLayout/HebrewIsRTLTest.java
@@ -0,0 +1,75 @@
+// Copyright 2019 Azul Systems, Inc.  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 Azul Systems, 385 Moffett Park Drive, Suite 115, Sunnyvale,
+// CA 94089 USA or visit www.azul.com if you need additional information or
+// have any questions.
+
+import java.awt.Font;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+/*
+ * @test
+ * @summary Fix to 8215210 should not break RTL with AAT fonts.
+ * @run main/othervm  -Dsun.font.layoutengine=icu HebrewIsRTLTest
+ */
+public class HebrewIsRTLTest {
+    static final String hebrewString = "\u05E9\u059E\u05E9\u0595\u05E9\u05A9\u05E9\u0592\u05E9\u0599\u05E9\u059E\u05E9\u0595\u05E9\u05A9\u05E9\u0592\u05E9\u0599  .  \u05E9\u0599\u05E9\u05A1\u05E9\u0595\u05E9\u0593";
+    public static void main(String args[]) {
+        if (!System.getProperty("os.name").startsWith("Mac")) {
+            return;
+        }
+
+        // calculate text size
+        BufferedImage biMetrics = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_RGB);
+        Graphics2D biMetricsGraphics = biMetrics.createGraphics();
+        Font font = new Font("TimesRoman", Font.PLAIN, 40);
+        biMetricsGraphics.setFont(font);
+        int width = biMetricsGraphics.getFontMetrics().stringWidth(hebrewString);
+        int height = biMetricsGraphics.getFontMetrics().getHeight();
+
+        // create minimal image
+        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        Graphics2D biGraphics = bi.createGraphics();
+        biGraphics.setColor(Color.white);
+        biGraphics.fillRect(0, 0, width, height);
+        biGraphics.setColor(Color.black);
+        biGraphics.setFont(font);
+        biGraphics.drawString(hebrewString, 0, height);
+
+        int y = bi.getHeight() / 2;
+        int x;
+        int rgb, rgbLeftCount = 0, rgbRightCount = 0;
+
+        for (x = 0; x < bi.getWidth()/2; x++) {
+            rgb = bi.getRGB(x, y);
+            if (rgb == Color.BLACK.getRGB()) {
+                rgbLeftCount++;
+            }
+        }
+        for (x = bi.getWidth()/2 + 1; x < bi.getWidth(); x++) {
+            rgb = bi.getRGB(x, y);
+            if (rgb == Color.BLACK.getRGB()) {
+                rgbRightCount++;
+            }
+        }
+        if (rgbLeftCount > rgbRightCount) {
+            throw new RuntimeException("Hebrew text seems drawn LTR");
+        }
+    }
+}
diff --git a/test/java/io/Serializable/serialFilter/GlobalFilterTest.java b/test/java/io/Serializable/serialFilter/GlobalFilterTest.java
index 20503d1..3810f38 100644
--- a/test/java/io/Serializable/serialFilter/GlobalFilterTest.java
+++ b/test/java/io/Serializable/serialFilter/GlobalFilterTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -42,9 +42,11 @@
 import sun.misc.ObjectInputFilter;
 
 /* @test
+ * @bug 8231422
  * @build GlobalFilterTest SerialFilterTest
  * @run testng/othervm GlobalFilterTest
- * @run testng/othervm -Djdk.serialFilter=java.** GlobalFilterTest
+ * @run testng/othervm -Djdk.serialFilter=java.**
+ *          -Dexpected-jdk.serialFilter=java.** GlobalFilterTest
  * @run testng/othervm/policy=security.policy GlobalFilterTest
  * @run testng/othervm/policy=security.policy
  *        -Djava.security.properties=${test.src}/java.security-extra1
@@ -54,6 +56,10 @@
  */
 @Test
 public class GlobalFilterTest {
+    private static final String serialPropName = "jdk.serialFilter";
+    private static final String badSerialFilter = "java.lang.StringBuffer;!*";
+    private static final String origSerialFilterProperty =
+            System.setProperty(serialPropName, badSerialFilter);
 
     /**
      * DataProvider of patterns and objects derived from the configured process-wide filter.
@@ -62,8 +68,8 @@
     @DataProvider(name="globalPatternElements")
     Object[][] globalPatternElements() {
         String globalFilter =
-                System.getProperty("jdk.serialFilter",
-                        Security.getProperty("jdk.serialFilter"));
+                System.getProperty("expected-" + serialPropName,
+                        Security.getProperty(serialPropName));
         if (globalFilter == null) {
             return new Object[0][];
         }
@@ -100,12 +106,20 @@
      */
     @Test()
     static void globalFilter() {
-        String pattern =
-                System.getProperty("jdk.serialFilter",
-                        Security.getProperty("jdk.serialFilter"));
         ObjectInputFilter filter = ObjectInputFilter.Config.getSerialFilter();
+
+        // Check that the System.setProperty(jdk.serialFilter) DOES NOT affect the filter.
+        String asSetSystemProp = System.getProperty(serialPropName,
+                Security.getProperty(serialPropName));
+        Assert.assertNotEquals(Objects.toString(filter, null), asSetSystemProp,
+                "System.setProperty(\"jdk.serialfilter\", ...) should not change filter: " +
+                asSetSystemProp);
+
+        String pattern =
+               System.getProperty("expected-" + serialPropName,
+                       Security.getProperty(serialPropName));
         System.out.printf("global pattern: %s, filter: %s%n", pattern, filter);
-        Assert.assertEquals(pattern, Objects.toString(filter, null),
+        Assert.assertEquals(Objects.toString(filter, null), pattern,
                 "process-wide filter pattern does not match");
     }
 
diff --git a/test/java/io/Serializable/serialFilter/security.policy b/test/java/io/Serializable/serialFilter/security.policy
index f986e25..a79251b 100644
--- a/test/java/io/Serializable/serialFilter/security.policy
+++ b/test/java/io/Serializable/serialFilter/security.policy
@@ -3,7 +3,7 @@
         // Specific permission under test
         permission java.security.SerializablePermission "serialFilter";
         // Permissions needed to run the test
-        permission java.util.PropertyPermission "*", "read";
+        permission java.util.PropertyPermission "*", "read,write";
         permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
         permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
         permission java.security.SecurityPermission "*";
diff --git a/test/java/lang/ProcessBuilder/Basic.java b/test/java/lang/ProcessBuilder/Basic.java
index 1db1d31..7a9260a 100644
--- a/test/java/lang/ProcessBuilder/Basic.java
+++ b/test/java/lang/ProcessBuilder/Basic.java
@@ -61,6 +61,15 @@
     /* used for AIX only */
     static final String libpath = System.getenv("LIBPATH");
 
+    /**
+     * Returns the number of milliseconds since time given by
+     * startNanoTime, which must have been previously returned from a
+     * call to {@link System.nanoTime()}.
+     */
+    private static long millisElapsedSince(long startNanoTime) {
+        return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
+    }
+
     private static String commandOutput(Reader r) throws Throwable {
         StringBuilder sb = new StringBuilder();
         int c;
@@ -2294,40 +2303,98 @@
 
         //----------------------------------------------------------------
         // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
-        // interrupt works as expected.
+        // interrupt works as expected, if interrupted while waiting.
         //----------------------------------------------------------------
         try {
             List<String> childArgs = new ArrayList<String>(javaChildArgs);
             childArgs.add("sleep");
             final Process p = new ProcessBuilder(childArgs).start();
             final long start = System.nanoTime();
-            final CountDownLatch ready = new CountDownLatch(1);
-            final CountDownLatch done = new CountDownLatch(1);
+            final CountDownLatch aboutToWaitFor = new CountDownLatch(1);
 
             final Thread thread = new Thread() {
                 public void run() {
                     try {
-                        final boolean result;
-                        try {
-                            ready.countDown();
-                            result = p.waitFor(30000, TimeUnit.MILLISECONDS);
-                        } catch (InterruptedException e) {
-                            return;
-                        }
+                        aboutToWaitFor.countDown();
+                        Thread.currentThread().interrupt();
+                        boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
                         fail("waitFor() wasn't interrupted, its return value was: " + result);
-                    } catch (Throwable t) {
-                        unexpected(t);
-                    } finally {
-                        done.countDown();
-                    }
+                    } catch (InterruptedException success) {
+                    } catch (Throwable t) { unexpected(t); }
                 }
             };
 
             thread.start();
-            ready.await();
-            Thread.sleep(1000);
+            aboutToWaitFor.await();
             thread.interrupt();
-            done.await();
+            thread.join(10L * 1000L);
+            check(millisElapsedSince(start) < 10L * 1000L);
+            check(!thread.isAlive());
+            p.destroy();
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // Check that Process.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS)
+        // interrupt works as expected, if interrupted while waiting.
+        //----------------------------------------------------------------
+        try {
+            List<String> childArgs = new ArrayList<String>(javaChildArgs);
+            childArgs.add("sleep");
+            final Process p = new ProcessBuilder(childArgs).start();
+            final long start = System.nanoTime();
+            final CountDownLatch aboutToWaitFor = new CountDownLatch(1);
+
+            final Thread thread = new Thread() {
+                public void run() {
+                    try {
+                        aboutToWaitFor.countDown();
+                        Thread.currentThread().interrupt();
+                        boolean result = p.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+                        fail("waitFor() wasn't interrupted, its return value was: " + result);
+                    } catch (InterruptedException success) {
+                    } catch (Throwable t) { unexpected(t); }
+                }
+            };
+
+            thread.start();
+            aboutToWaitFor.await();
+            thread.interrupt();
+            thread.join(10L * 1000L);
+            check(millisElapsedSince(start) < 10L * 1000L);
+            check(!thread.isAlive());
+            p.destroy();
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
+        // interrupt works as expected, if interrupted before waiting.
+        //----------------------------------------------------------------
+        try {
+            List<String> childArgs = new ArrayList<String>(javaChildArgs);
+            childArgs.add("sleep");
+            final Process p = new ProcessBuilder(childArgs).start();
+            final long start = System.nanoTime();
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+
+            final Thread thread = new Thread() {
+                public void run() {
+                    try {
+                        threadStarted.countDown();
+                        do { Thread.yield(); }
+                        while (!Thread.currentThread().isInterrupted());
+                        boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
+                        fail("waitFor() wasn't interrupted, its return value was: " + result);
+                    } catch (InterruptedException success) {
+                    } catch (Throwable t) { unexpected(t); }
+                }
+            };
+
+            thread.start();
+            threadStarted.await();
+            thread.interrupt();
+            thread.join(10L * 1000L);
+            check(millisElapsedSince(start) < 10L * 1000L);
+            check(!thread.isAlive());
             p.destroy();
         } catch (Throwable t) { unexpected(t); }
 
diff --git a/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java b/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
new file mode 100644
index 0000000..62eac12
--- /dev/null
+++ b/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2018, Amazon and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, Inc. 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 8231584
+ * @library /lib/testlibrary
+ * @run main/othervm LoadLibraryTest
+ */
+
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.Path;
+import java.net.MalformedURLException;
+import java.net.URLClassLoader;
+import java.net.URL;
+
+public class LoadLibraryTest {
+    static Thread thread1 = null;
+    static Thread thread2 = null;
+
+    static volatile boolean thread1Ready = false;
+
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path CLS_DIR = Paths.get("classes");
+
+    static TestClassLoader loader;
+    static void someLibLoad() {
+        try {
+/*
+            FileSystems.getDefault();
+
+            // jdk/jdk: loads directly from Bootstrap Classloader (doesn't take lock on Runtime)
+            java.net.NetworkInterface.getNetworkInterfaces();
+
+            System.out.println(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
+*/
+            Class c = Class.forName("Target2", true, loader);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static class TestClassLoader extends URLClassLoader {
+        boolean passed = false;
+
+        public boolean passed() {
+            return passed;
+        }
+
+        TestClassLoader() throws MalformedURLException {
+            super(new URL[] { new URL("file://" + CLS_DIR.toAbsolutePath().toString() + '/') });
+        }
+
+        public String findLibrary(String name) {
+            System.out.println("findLibrary " + name);
+
+            if ("someLibrary".equals(name)) {
+                try {
+                    synchronized(thread1) {
+                        while(!thread1Ready) {
+                            thread1.wait();
+                        }
+                        thread1.notifyAll();
+                    }
+
+                    Thread.sleep(10000);
+
+                    System.out.println("Thread2 load");
+                    someLibLoad();
+
+                    // no deadlock happened
+                    passed = true;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                return null;
+            }
+
+            return super.findLibrary(name);
+        }
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        loader = new TestClassLoader();
+
+        if (!CompilerUtils.compile(SRC_DIR, CLS_DIR)) {
+            throw new Exception("Can't compile");
+        }
+
+        thread1 = new Thread() {
+            public void run() {
+                try {
+                    synchronized(this) {
+                        thread1Ready = true;
+                        thread1.notifyAll();
+                        thread1.wait();
+                    }
+                } catch(InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+
+                System.out.println("Thread1 load");
+                someLibLoad();
+            };
+        };
+
+        thread2 = new Thread() {
+            public void run() {
+                try {
+                    Class c = Class.forName("Target", true, loader);
+                    System.out.println(c);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            };
+        };
+
+        thread1.setDaemon(true);
+        thread2.setDaemon(true);
+
+        thread1.start();
+        thread2.start();
+
+        thread1.join();
+        thread2.join();
+
+        if (!loader.passed()) {
+            throw new RuntimeException("FAIL");
+        }
+    }
+}
diff --git a/test/java/lang/Runtime/loadLibrary/src/Target.java b/test/java/lang/Runtime/loadLibrary/src/Target.java
new file mode 100644
index 0000000..fc51481
--- /dev/null
+++ b/test/java/lang/Runtime/loadLibrary/src/Target.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, Azul Systems, Inc. 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.
+ */
+
+class Target {
+    static {
+        try {
+            System.loadLibrary("someLibrary");
+            throw new RuntimeException("someLibrary was loaded");
+        } catch (UnsatisfiedLinkError e) {
+            // expected: we do not have a someLibrary
+        }
+    }
+}
+
diff --git a/test/java/lang/Runtime/loadLibrary/src/Target2.java b/test/java/lang/Runtime/loadLibrary/src/Target2.java
new file mode 100644
index 0000000..bc8dfc5
--- /dev/null
+++ b/test/java/lang/Runtime/loadLibrary/src/Target2.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019, Azul Systems, Inc. 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.
+ */
+
+class Target2 {
+    static {
+        System.loadLibrary("awt");
+    }
+}
+
diff --git a/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java b/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java
index 2d79c61..3258925 100644
--- a/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java
+++ b/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -25,15 +25,18 @@
  * @test
  * @summary Test consistent parsing of ex-RUNTIME annotations that
  *          were changed and separately compiled to have CLASS retention
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main AnnotationTypeRuntimeAssumptionTest
  */
 
-import sun.misc.IOUtils;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import jdk.testlibrary.IOUtils;
+
 import static java.lang.annotation.RetentionPolicy.CLASS;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
@@ -137,7 +140,7 @@
                 String altPath = altName.replace('.', '/').concat(".class");
                 try (InputStream is = getResourceAsStream(altPath)) {
                     if (is != null) {
-                        byte[] bytes = IOUtils.readFully(is, -1, true);
+                        byte[] bytes = IOUtils.readFully(is);
                         // patch class bytes to contain original name
                         for (int i = 0; i < bytes.length - 2; i++) {
                             if (bytes[i] == '_' &&
@@ -160,7 +163,7 @@
                 String path = name.replace('.', '/').concat(".class");
                 try (InputStream is = getResourceAsStream(path)) {
                     if (is != null) {
-                        byte[] bytes = IOUtils.readFully(is, -1, true);
+                        byte[] bytes = IOUtils.readFully(is);
                         return defineClass(name, bytes, 0, bytes.length);
                     }
                     else {
diff --git a/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java b/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java
index 9d38102..6c97e34 100644
--- a/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java
+++ b/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -22,11 +22,14 @@
  */
 
 /*
-@test
-@bug 8004970
-@summary Lambda serialization in the presence of class loaders
-@author Peter Levart
-*/
+ * @test
+ * @bug 8004970
+ * @summary Lambda serialization in the presence of class loaders
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main LambdaClassLoaderSerialization
+ * @author Peter Levart
+ */
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -37,6 +40,8 @@
 import java.io.Serializable;
 import java.util.Arrays;
 
+import jdk.testlibrary.IOUtils;
+
 public class LambdaClassLoaderSerialization {
 
     public interface SerializableRunnable extends Runnable, Serializable {}
@@ -125,7 +130,7 @@
             String path = name.replace('.', '/').concat(".class");
             try (InputStream is = getResourceAsStream(path)) {
                 if (is != null) {
-                    byte[] bytes = readFully(is);
+                    byte[] bytes = IOUtils.readFully(is);
                     return defineClass(name, bytes, 0, bytes.length);
                 } else {
                     throw new ClassNotFoundException(name);
@@ -135,30 +140,5 @@
                 throw new ClassNotFoundException(name, e);
             }
         }
-
-        static byte[] readFully(InputStream is) throws IOException {
-            byte[] output = {};
-            int pos = 0;
-            while (true) {
-                int bytesToRead;
-                if (pos >= output.length) { // Only expand when there's no room
-                    bytesToRead = output.length + 1024;
-                    if (output.length < pos + bytesToRead) {
-                        output = Arrays.copyOf(output, pos + bytesToRead);
-                    }
-                } else {
-                    bytesToRead = output.length - pos;
-                }
-                int cc = is.read(output, pos, bytesToRead);
-                if (cc < 0) {
-                    if (output.length != pos) {
-                        output = Arrays.copyOf(output, pos);
-                    }
-                    break;
-                }
-                pos += cc;
-            }
-            return output;
-        }
     }
 }
diff --git a/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java b/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
index ffb384f..4ad93eb 100644
--- a/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
+++ b/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -27,6 +27,9 @@
  * @summary Test that a static method on an interface doesn't hide a default
  *          method with the same name and signature in a separate compilation
  *          scenario.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main StaticInterfaceMethodInWayOfDefault
  */
 
 import java.io.IOException;
@@ -35,7 +38,7 @@
 import java.lang.reflect.Method;
 import java.util.concurrent.Callable;
 
-import sun.misc.IOUtils;
+import jdk.testlibrary.IOUtils;
 
 public class StaticInterfaceMethodInWayOfDefault {
     public interface A_v1 {
@@ -144,7 +147,7 @@
                 String altPath = altName.replace('.', '/').concat(".class");
                 try (InputStream is = getResourceAsStream(altPath)) {
                     if (is != null) {
-                        byte[] bytes = IOUtils.readFully(is, -1, true);
+                        byte[] bytes = IOUtils.readFully(is);
                         // patch class bytes to contain original name
                         for (int i = 0; i < bytes.length - 2; i++) {
                             if (bytes[i] == '_' &&
@@ -167,7 +170,7 @@
                 String path = name.replace('.', '/').concat(".class");
                 try (InputStream is = getResourceAsStream(path)) {
                     if (is != null) {
-                        byte[] bytes = IOUtils.readFully(is, -1, true);
+                        byte[] bytes = IOUtils.readFully(is);
                         return defineClass(name, bytes, 0, bytes.length);
                     }
                     else {
diff --git a/test/java/net/CookieHandler/B6791927.java b/test/java/net/CookieHandler/B6791927.java
index 4b87015..bc5374b 100644
--- a/test/java/net/CookieHandler/B6791927.java
+++ b/test/java/net/CookieHandler/B6791927.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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,8 +23,9 @@
 
 /**
  * @test
- * @bug 6791927
+ * @bug 6791927 8233886
  * @summary Wrong Locale in HttpCookie::expiryDate2DeltaSeconds
+ * @run main/othervm B6791927
  */
 
 import java.net.*;
@@ -32,12 +33,14 @@
 import java.util.Locale;
 
 public class B6791927 {
-    public static final void main( String[] aaParamters ) throws Exception{
+    public static final void main(String[] aaParamters) throws Exception {
         Locale reservedLocale = Locale.getDefault();
         try {
             // Forces a non US locale
             Locale.setDefault(Locale.FRANCE);
-            List<HttpCookie> cookies = HttpCookie.parse("set-cookie: CUSTOMER=WILE_E_COYOTE; expires=Sat, 09-Nov-2019 23:12:40 GMT");
+            List<HttpCookie> cookies = HttpCookie.parse("set-cookie:" +
+                    " CUSTOMER=WILE_E_COYOTE;" +
+                    " expires=Sat, 09-Nov-2041 23:12:40 GMT");
             if (cookies == null || cookies.isEmpty()) {
                 throw new RuntimeException("No cookie found");
             }
diff --git a/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java b/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java
index 75bf2ec..79dce7e 100644
--- a/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java
+++ b/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java
@@ -29,12 +29,12 @@
 
 /**
  * @test
- * @bug 6852744
+ * @bug 6852744 8133489
  * @summary PIT b61: PKI test suite fails because self signed certificates
  *          are being rejected
- * @run main/othervm KeyUsageMatters subca
- * @run main/othervm KeyUsageMatters subci
- * @run main/othervm KeyUsageMatters alice
+ * @run main/othervm -Djava.security.debug=certpath KeyUsageMatters subca
+ * @run main/othervm -Djava.security.debug=certpath KeyUsageMatters subci
+ * @run main/othervm -Djava.security.debug=certpath KeyUsageMatters alice
  * @author Xuelei Fan
  */
 
diff --git a/test/java/security/testlibrary/Proc.java b/test/java/security/testlibrary/Proc.java
index 1ab58bf..95192cd 100644
--- a/test/java/security/testlibrary/Proc.java
+++ b/test/java/security/testlibrary/Proc.java
@@ -235,6 +235,13 @@
         br = new BufferedReader(new InputStreamReader(p.getInputStream()));
         return this;
     }
+    String getId(String suffix) {
+        if (debug != null) {
+            return debug + "." + suffix;
+        } else {
+            return System.identityHashCode(this) + "." + suffix;
+        }
+    }
     // Reads a line from stdout of proc
     public String readLine() throws IOException {
         String s = br.readLine();
@@ -303,9 +310,13 @@
         boolean isEmpty = true;
         while (true) {
             int i = System.in.read();
-            if (i == -1) break;
+            if (i == -1) {
+                break;
+            }
             isEmpty = false;
-            if (i == '\n') break;
+            if (i == '\n') {
+                break;
+            }
             if (i != 13) {
                 // Force it to a char, so only simple ASCII works.
                 sb.append((char)i);
diff --git a/test/javax/swing/ToolTipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java b/test/javax/swing/ToolTipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java
new file mode 100644
index 0000000..dae2509
--- /dev/null
+++ b/test/javax/swing/ToolTipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2019, 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
+ * @key headful
+ * @bug 8225505
+ * @summary CTRL + 1 does not show tooltip message for menu items
+ * @run main/manual JMenuItemToolTipKeyBindingsTest
+ */
+
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.SwingUtilities;
+import java.awt.Button;
+import java.awt.Dialog;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class JMenuItemToolTipKeyBindingsTest {
+    private static final long TIMEOUT = 5 * 60 * 1000;
+    private static final AtomicBoolean testCompleted = new AtomicBoolean(false);
+    private static volatile boolean testResult = false;
+
+    private static Dialog controlDialog;
+    private static JFrame testFrame;
+
+    private static final String instructions =
+            "Verify that \"CTRL\" + \"F1\" key sequence shows/hides tool tip message" +
+            "\nfor menu items.\n" +
+            "\n1. Open pop-up menu \"Menu\", (i.e. press \"F10\")." +
+            "\n2. Navigate to some menu element using keyboard." +
+            "\n3. Press \"CTRL\" + \"F1\" once menu item is selected." +
+            "\nIf tooltip message is displayed for the item then press \"Pass\"," +
+            "\n otherwise press \"Fail\".";
+
+    public static void main(String[] args) throws Exception {
+        try {
+            SwingUtilities.invokeAndWait(() -> createAndShowGUI());
+
+            waitForCompleting();
+            if (!testResult) {
+                throw new RuntimeException("Test FAILED!");
+            }
+        } finally {
+            if (controlDialog != null) {
+                controlDialog.dispose();
+            }
+            if (testFrame != null) {
+                testFrame.dispose();
+            }
+        }
+    }
+
+    private static void createAndShowGUI() {
+        controlDialog = new Dialog((JFrame)null, "JMenuItemToolTipKeyBindingsTest");
+
+        TextArea messageArea = new TextArea(instructions, 15, 80, TextArea.SCROLLBARS_BOTH);
+        controlDialog.add("North", messageArea);
+
+        Button passedButton = new Button("Pass");
+        passedButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                testResult = true;
+                completeTest();
+            }
+        });
+
+        Button failedButton = new Button("Fail");
+        failedButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                testResult = false;
+                completeTest();
+            }
+        });
+
+        Panel buttonPanel = new Panel();
+        buttonPanel.add("West",passedButton);
+        buttonPanel.add("East", failedButton);
+        controlDialog.add("South", buttonPanel);
+
+        controlDialog.setBounds(250, 0, 500, 500);
+        controlDialog.setVisible(true);
+
+        testFrame = new JFrame("JMenuItemToolTipKeyBindingsTest");
+        testFrame.setSize(200, 200);
+        JMenuBar jMenuBar = new JMenuBar();
+        JMenu jMenu = new JMenu("Menu");
+        for (int i = 0; i < 3; i++) {
+            JMenuItem jMenuItem = new JMenuItem("Item " + i);
+            jMenuItem.setToolTipText("Tooltip " + i);
+            jMenu.add(jMenuItem);
+        }
+        jMenuBar.add(jMenu);
+        testFrame.setJMenuBar(jMenuBar);
+        testFrame.setVisible(true);
+    }
+
+    private static void completeTest() {
+        testCompleted.set(true);
+        synchronized (testCompleted) {
+            testCompleted.notifyAll();
+        }
+    }
+
+    private static void waitForCompleting() throws Exception {
+        synchronized (testCompleted) {
+            long startTime = System.currentTimeMillis();
+            while (!testCompleted.get()) {
+                testCompleted.wait(TIMEOUT);
+                if (System.currentTimeMillis() - startTime >= TIMEOUT) {
+                    break;
+                }
+            }
+        }
+    }
+}
+
diff --git a/test/jbProblemsList.txt b/test/jbProblemsList.txt
index f548ea1..4939b41 100644
--- a/test/jbProblemsList.txt
+++ b/test/jbProblemsList.txt
@@ -118,7 +118,7 @@
 java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java                6848406 generic-all
 java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java            6829264 generic-all
 java/awt/Focus/ChoiceFocus/ChoiceFocus.java                                         8169103 windows-all,macosx-all,linux-all
-java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java                     8198618 macosx-all
+java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java                     8198618 macosx-all,linux-all
 java/awt/Focus/CloseDialogActivateOwnerTest/CloseDialogActivateOwnerTest.java       7124555 generic-all
 java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252 macosx-all
 java/awt/Focus/DeiconifiedFrameLoosesFocus/DeiconifiedFrameLoosesFocus.html         8015886 generic-all
@@ -164,7 +164,9 @@
 java/awt/Graphics2D/FlipDrawImage/FlipDrawImage.java                                8169462 windows-all
 java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java                  8145808 generic-all
 java/awt/Graphics2D/WhiteTextColorTest.java                                         8054638 generic-all
+java/awt/GraphicsDevice/IncorrectDisplayModeExitFullscreen.java                     8134672 linux-all
 java/awt/GridLayout/LayoutExtraGaps/LayoutExtraGaps.java                            8000171 windows-all
+java/awt/Gtk/GtkVersionTest/GtkVersionTest.java                                     8237068 linux-all
 java/awt/JAWT/JAWT.sh                                                               8197798,8170729 generic-all
 java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.html        8158380,8198624 generic-all
 java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.html                    8198626,8074807 generic-all
@@ -236,6 +238,7 @@
 java/awt/Window/AlwaysOnTop/SyncAlwaysOnTopFieldTest.java                           8198739 windows-all
 java/awt/Window/AlwaysOnTop/TestAlwaysOnTopBeforeShow.java                          8032450,8169530 generic-all
 java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java                  8142536 generic-all
+java/awt/Window/GetScreenLocation/GetScreenLocationTest.java                        8225787 linux-all
 java/awt/Window/Grab/GrabTest.java                                                  8047703 generic-all
 java/awt/Window/GrabSequence/GrabSequence.java                                      6848409 macosx-all,windows-all,linux-all
 java/awt/Window/WindowsLeak/WindowsLeak.java                                        8028486 macosx-all
@@ -281,6 +284,7 @@
 java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java           6956646 generic-all
 java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.html           6956646 generic-all
 java/awt/event/MouseWheelEvent/WheelModifier/WheelModifier.java                     8169475 generic-all
+java/awt/font/FontScaling/FontScalingTest.java                                      8159465 linux-all
 java/awt/font/PhoneticExtensions/PhoneticExtensionsGlyphTest.java                   8202696 windows-all
 java/awt/font/TextLayout/CombiningPerf.java                                         8192931,7043170 generic-all
 java/awt/font/TextLayout/OSXLigatureTest.java                                       7162125 macosx-all
@@ -634,6 +638,7 @@
 javax/swing/JOptionPane/6464022/bug6464022.java                                       7124548 macosx-all
 javax/swing/JPopupMenu/4458079/bug4458079.java                                        8040917 generic-all
 javax/swing/JPopupMenu/4966112/bug4966112.java                                        8064915,8074385 generic-all
+javax/swing/JPopupMenu/6694823/bug6694823.java                                        7182533 linux-all
 javax/swing/JPopupMenu/6800513/bug6800513.java                                        8080868 generic-all
 javax/swing/JPopupMenu/6827786/bug6827786.java                                        8042378,8042378 generic-all
 javax/swing/JPopupMenu/6987844/bug6987844.java                                        8169956 generic-all
diff --git a/test/jdk/java/awt/font/Rotate/RotatedFontMetricsTest.java b/test/jdk/java/awt/font/Rotate/RotatedFontMetricsTest.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/jdk/java/awt/font/Rotate/RotatedFontMetricsTest.java
diff --git a/test/lib/testlibrary/ClassFileInstaller.java b/test/lib/testlibrary/ClassFileInstaller.java
index dd8777b..0f5b515 100644
--- a/test/lib/testlibrary/ClassFileInstaller.java
+++ b/test/lib/testlibrary/ClassFileInstaller.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,28 +21,229 @@
  * questions.
  */
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.io.ByteArrayInputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
 /**
- * Dump a class file for a class on the class path in the current directory
+ * Dump a class file for a class on the class path in the current directory, or
+ * in the specified JAR file. This class is usually used when you build a class
+ * from a test library, but want to use this class in a sub-process.
+ *
+ * For example, to build the following library class:
+ * test/lib/sun/hotspot/WhiteBox.java
+ *
+ * You would use the following tags:
+ *
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ *
+ * JTREG would build the class file under
+ * ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class
+ *
+ * With you run your main test class using "@run main MyMainClass", JTREG would setup the
+ * -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to
+ * load the WhiteBox class.
+ *
+ * However, if you run a sub process, and do not wish to use the exact same -classpath,
+ * You can use ClassFileInstaller to ensure that WhiteBox is available in the current
+ * directory of your test:
+ *
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *
+ * Or, you can use the -jar option to store the class in the specified JAR file. If a relative
+ * path name is given, the JAR file would be relative to the current directory of
+ *
+ * @run main ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox
  */
 public class ClassFileInstaller {
     /**
+     * You can enable debug tracing of ClassFileInstaller by running JTREG with
+     * jtreg -DClassFileInstaller.debug=true ... <names of tests>
+     */
+    public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug");
+
+    /**
      * @param args The names of the classes to dump
      * @throws Exception
      */
     public static void main(String... args) throws Exception {
-        for (String arg : args) {
-            ClassLoader cl = ClassFileInstaller.class.getClassLoader();
+        if (args.length > 1 && args[0].equals("-jar")) {
+            if (args.length < 2) {
+                throw new RuntimeException("Usage: ClassFileInstaller <options> <classes>\n" +
+                                           "where possible options include:\n" +
+                                           "  -jar <path>             Write to the JAR file <path>");
+            }
+            writeJar(args[1], null, args, 2, args.length);
+        } else {
+            if (DEBUG) {
+                System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir"));
+            }
+            for (String arg : args) {
+                writeClassToDisk(arg);
+            }
+        }
+    }
 
-            // Convert dotted class name to a path to a class file
-            String pathName = arg.replace('.', '/').concat(".class");
-            InputStream is = cl.getResourceAsStream(pathName);
+    public static class Manifest {
+        private InputStream in;
 
+        private Manifest(InputStream in) {
+            this.in = in;
+        }
+
+        static Manifest fromSourceFile(String fileName) throws Exception {
+            String pathName = System.getProperty("test.src") + File.separator + fileName;
+            return new Manifest(new FileInputStream(pathName));
+        }
+
+        // Example:
+        //  String manifest = "Premain-Class: RedefineClassHelper\n" +
+        //                "Can-Redefine-Classes: true\n";
+        //  ClassFileInstaller.writeJar("redefineagent.jar",
+        //    ClassFileInstaller.Manifest.fromString(manifest),
+        //    "RedefineClassHelper");
+        static Manifest fromString(String manifest) throws Exception {
+            return new Manifest(new ByteArrayInputStream(manifest.getBytes()));
+        }
+
+        public InputStream getInputStream() {
+            return in;
+        }
+    }
+
+    private static void writeJar(String jarFile, Manifest manifest, String classes[], int from, int to) throws Exception {
+        if (DEBUG) {
+            System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile));
+        }
+
+        (new File(jarFile)).delete();
+        FileOutputStream fos = new FileOutputStream(jarFile);
+        ZipOutputStream zos = new ZipOutputStream(fos);
+
+        // The manifest must be the first or second entry. See comments in JarInputStream
+        // constructor and JDK-5046178.
+        if (manifest != null) {
+            writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream());
+        }
+
+        for (int i=from; i<to; i++) {
+            writeClassToDisk(zos, classes[i]);
+        }
+
+        zos.close();
+        fos.close();
+    }
+
+    /*
+     * You can call ClassFileInstaller.writeJar() from your main test class instead of
+     * using "@run ClassFileInstaller -jar ...". E.g.,
+     *
+     * String jarPath = ClassFileInstaller.getJarPath("myjar.jar", "sun.hotspot.WhiteBox")
+     *
+     * If you call this API, make sure you build ClassFileInstaller with the following tags:
+     *
+     * @library testlibrary
+     * @build ClassFileInstaller
+     */
+    public static String writeJar(String jarFile, String... classes) throws Exception {
+        writeJar(jarFile, null, classes, 0, classes.length);
+        return getJarPath(jarFile);
+    }
+
+    public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception {
+        writeJar(jarFile, manifest, classes, 0, classes.length);
+        return getJarPath(jarFile);
+    }
+
+    /**
+     * This returns the absolute path to the file specified in "@ClassFileInstaller -jar myjar.jar",
+     * In your test program, instead of using the JAR file name directly:
+     *
+     * String jarPath = "myjar.jar";
+     *
+     * you should call this function, like:
+     *
+     * String jarPath = ClassFileInstaller.getJarPath("myjar.jar")
+     *
+     * The reasons are:
+     * (1) Using absolute path makes it easy to cut-and-paste from the JTR file and rerun your
+     *     test in any directory.
+     * (2) In the future, we may make the JAR file name unique to avoid clobbering
+     *     during parallel JTREG execution.
+     *
+     */
+    public static String getJarPath(String jarFileName) {
+        return new File(jarFileName).getAbsolutePath();
+    }
+
+    public static void writeClassToDisk(String className) throws Exception {
+        writeClassToDisk((ZipOutputStream)null, className);
+    }
+    private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception {
+        writeClassToDisk(zos, className, "");
+    }
+
+    public static void writeClassToDisk(String className, String prependPath) throws Exception {
+        writeClassToDisk(null, className, prependPath);
+    }
+    private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception {
+        ClassLoader cl = ClassFileInstaller.class.getClassLoader();
+
+        // Convert dotted class name to a path to a class file
+        String pathName = className.replace('.', '/').concat(".class");
+        InputStream is = cl.getResourceAsStream(pathName);
+        if (is == null) {
+            throw new RuntimeException("Failed to find " + pathName);
+        }
+        if (prependPath.length() > 0) {
+            pathName = prependPath + "/" + pathName;
+        }
+        writeToDisk(zos, pathName, is);
+    }
+
+    public static void writeClassToDisk(String className, byte[] bytecode) throws Exception {
+        writeClassToDisk(null, className, bytecode);
+    }
+    private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception {
+        writeClassToDisk(zos, className, bytecode, "");
+    }
+
+    public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception {
+        writeClassToDisk(null, className, bytecode, prependPath);
+    }
+    private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception {
+        // Convert dotted class name to a path to a class file
+        String pathName = className.replace('.', '/').concat(".class");
+        if (prependPath.length() > 0) {
+            pathName = prependPath + "/" + pathName;
+        }
+        writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode));
+    }
+
+    private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception {
+        if (DEBUG) {
+            System.out.println("ClassFileInstaller: Writing " + pathName);
+        }
+        if (zos != null) {
+            ZipEntry ze = new ZipEntry(pathName);
+            zos.putNextEntry(ze);
+            byte[] buf = new byte[1024];
+            int len;
+            while ((len = is.read(buf))>0){
+                zos.write(buf, 0, len);
+            }
+        } else {
             // Create the class file's package directory
             Path p = Paths.get(pathName);
             Path parent = p.getParent();
@@ -52,5 +253,6 @@
             // Create the class file
             Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
         }
+        is.close();
     }
 }
diff --git a/test/lib/testlibrary/jdk/testlibrary/FileUtils.java b/test/lib/testlibrary/jdk/testlibrary/FileUtils.java
index b9f3088..587bf82 100644
--- a/test/lib/testlibrary/jdk/testlibrary/FileUtils.java
+++ b/test/lib/testlibrary/jdk/testlibrary/FileUtils.java
@@ -228,4 +228,3 @@
         return areFileSystemsAccessible;
     }
 }
-
diff --git a/test/lib/testlibrary/jdk/testlibrary/IOUtils.java b/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
new file mode 100644
index 0000000..4bfddd0
--- /dev/null
+++ b/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary;
+
+/**
+ * Defines useful I/O methods.
+ */
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+public final class IOUtils {
+
+    /*
+     * Prevent instantiation.
+     */
+    private IOUtils() {}
+
+    /**
+     * Read all bytes from <code>in</code>
+     * until EOF is detected.
+     * @param in input stream, must not be null
+     * @return bytes read
+     * @throws IOException Any IO error.
+     */
+    public static byte[] readFully(InputStream is) throws IOException {
+        byte[] output = {};
+        int pos = 0;
+        while (true) {
+            int bytesToRead;
+            if (pos >= output.length) { // Only expand when there's no room
+                bytesToRead = output.length + 1024;
+                if (output.length < pos + bytesToRead) {
+                    output = Arrays.copyOf(output, pos + bytesToRead);
+                }
+            } else {
+                bytesToRead = output.length - pos;
+            }
+            int cc = is.read(output, pos, bytesToRead);
+            if (cc < 0) {
+                if (output.length != pos) {
+                    output = Arrays.copyOf(output, pos);
+                }
+                break;
+            }
+            pos += cc;
+        }
+        return output;
+    }
+}
diff --git a/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java b/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java
new file mode 100644
index 0000000..6cb5006
--- /dev/null
+++ b/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2019, 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 8233223
+ * @summary Interoperability tests with Amazon's CA1, CA2, CA3, and CA4
+ * @build ValidatePathWithParams
+ * @run main/othervm -Djava.security.debug=certpath AmazonCA OCSP
+ * @run main/othervm -Djava.security.debug=certpath AmazonCA CRL
+ */
+
+/*
+ * Obtain TLS test artifacts for Amazon CAs from:
+ *
+ * Amazon Root CA 1
+ *     Valid - https://good.sca1a.amazontrust.com/
+ *     Revoked - https://revoked.sca1a.amazontrust.com/
+ * Amazon Root CA 2
+ *     Valid - https://good.sca2a.amazontrust.com/
+ *     Revoked - https://revoked.sca2a.amazontrust.com/
+ * Amazon Root CA 3
+ *     Valid - https://good.sca3a.amazontrust.com/
+ *     Revoked - https://revoked.sca3a.amazontrust.com/
+ * Amazon Root CA 4
+ *     Valid - https://good.sca4a.amazontrust.com/
+ *     Revoked - https://revoked.sca4a.amazontrust.com/
+ */
+public class AmazonCA {
+
+    public static void main(String[] args) throws Exception {
+
+        ValidatePathWithParams pathValidator = new ValidatePathWithParams(null);
+        boolean ocspEnabled = false;
+
+        if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) {
+            pathValidator.enableCRLCheck();
+        } else {
+            // OCSP check by default
+            pathValidator.enableOCSPCheck();
+            ocspEnabled = true;
+        }
+
+        new AmazonCA_1().runTest(pathValidator, ocspEnabled);
+        new AmazonCA_2().runTest(pathValidator, ocspEnabled);
+        new AmazonCA_3().runTest(pathValidator, ocspEnabled);
+        new AmazonCA_4().runTest(pathValidator, ocspEnabled);
+    }
+}
+
+class AmazonCA_1 {
+
+    // Owner: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US
+    // Issuer: CN=Amazon Root CA 1, O=Amazon, C=US
+    // Serial number: 67f9457508c648c09ca652e71791830e72592
+    // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+    private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIERzCCAy+gAwIBAgITBn+UV1CMZIwJymUucXkYMOclkjANBgkqhkiG9w0BAQsF\n" +
+            "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" +
+            "b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" +
+            "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" +
+            "IDFBMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" +
+            "AoIBAQCeQM3XCsIZunv8bSJxOqkc/ed87uL76FDB7teBNThDRB+1J7aITuadbNfH\n" +
+            "5ZfZykrdZ1qQLKxP6DwHOmJr9u2b4IxjUX9qUMuq4B02ghD2g6yU3YivEosZ7fpo\n" +
+            "srD2TBN29JpgPGrOrpOE+ArZuIpBjdKFinemu6fTDD0NCeQlfyHXd1NOYyfYRLTa\n" +
+            "xlpDqr/2M41BgSkWQfSPHHyRWNQgWBiGsIQaS8TK0g8OWi1ov78+2K9DWT+AHgXW\n" +
+            "AanjZK91GfygPXJYSlAGxSiBAwH/KhAMifhaoFYAbH0Yuohmd85B45G2xVsop4TM\n" +
+            "Dsl007U7qnS7sdJ4jYGzEvva/a95AgMBAAGjggE5MIIBNTASBgNVHRMBAf8ECDAG\n" +
+            "AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUYtRCXoZwdWqQvMa40k1g\n" +
+            "wjS6UTowHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH\n" +
+            "AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy\n" +
+            "dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy\n" +
+            "dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js\n" +
+            "LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBEGA1UdIAQKMAgw\n" +
+            "BgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEAMHbSWHRFMzGNIE0qhN6gnRahTrTU\n" +
+            "CDPwe7l9/q0IA+QBlrpUHnlAreetYeH1jB8uF3qXXzy22gpBU7NqulTkqSPByT1J\n" +
+            "xOhpT2FpO5R3VAdMPdWfSEgtrED0jkmyUQrR1T+/A+nBLdJZeQcl+OqLgeY790JM\n" +
+            "JJTsJnnI6FBWeTGhcDI4Y+n3KS3QCVePeWI7jx1dhrHcXH+QDX8Ywe31hV7YENdr\n" +
+            "HDpUXrjK6eHN8gazy8G6pndXHFwHp4auiZbJbYAk/q1peOTRagD2JojcLkm+i3cD\n" +
+            "843t4By6YT/PVlePU2PCWejkrJQnKQAPOov7IA8kuO2RDWuzE/zF6Hotdg==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=good.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US
+    // Serial number: 703e4e4bbd78e2b6db5634f36c4ee944cb1a4
+    // Valid from: Mon Jul 29 16:53:36 PDT 2019 until: Sat Aug 29 16:53:36 PDT 2020
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIFEzCCA/ugAwIBAgITBwPk5LvXjitttWNPNsTulEyxpDANBgkqhkiG9w0BAQsF\n" +
+            "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+            "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzUzMzZaFw0yMDA4\n" +
+            "MjkyMzUzMzZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+            "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" +
+            "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" +
+            "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" +
+            "czEjMCEGA1UEAxMaZ29vZC5zY2ExYS5hbWF6b250cnVzdC5jb20wggEiMA0GCSqG\n" +
+            "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQyuJ83c2Zf9k29f6iLqd8nJSuHSk1v+SS\n" +
+            "0sYyG8tjscfCC1HcOdNj37vtiNN65sXh/e/kBKH9wvzhCLOJbBqVKRHOZuHdJEpH\n" +
+            "35R6C/PbcV/tp49g6mNmBe+lcmm/cwwCtYvkL0rgL/OKB0liFhhRIqy2TPg08op/\n" +
+            "RlY2DdbgBA2B3g7wdMo0hK3SO56/QUccUtLRm43km9Yd4E3U+CEUyDd0Bmc/YbPa\n" +
+            "htuXVsXJwiwlwooomujIIENhFw3htdcsu2apRj8EYUrKL8Mvvn+h16gDyobj0f01\n" +
+            "jWXlUgmH2lzUzca5eGuphfvmWN/ME/yqC2mMvWGnWySycqtT8VdJAgMBAAGjggFj\n" +
+            "MIIBXzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYEFFENOZBwFkjVdQX0iK32c77z\n" +
+            "SUl6MB8GA1UdIwQYMBaAFGLUQl6GcHVqkLzGuNJNYMI0ulE6MB0GA1UdJQQWMBQG\n" +
+            "CCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGG\n" +
+            "IWh0dHA6Ly9vY3NwLnNjYTFhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYq\n" +
+            "aHR0cDovL2NydC5zY2ExYS5hbWF6b250cnVzdC5jb20vc2NhMWEuY2VyMCUGA1Ud\n" +
+            "EQQeMByCGmdvb2Quc2NhMWEuYW1hem9udHJ1c3QuY29tMFAGA1UdIARJMEcwDQYL\n" +
+            "YIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcCARYfaHR0cHM6Ly93d3cu\n" +
+            "YW1hem9udHJ1c3QuY29tL2NwczANBgkqhkiG9w0BAQsFAAOCAQEAmn7z6Ub1sL77\n" +
+            "wyUEaCq/Odqm+2RtYYMJ1MeW6nTXTfAgZ/iLx/6hStafd9AK9gHiTCggBpj6KgnF\n" +
+            "UsGMDeX879jP675fH6SEk710QPDhIrfAzwE0pF/eUNsd7pLwne32zHX0ouCoAt4d\n" +
+            "KwBCZkKNUkdj4U+bpOJzvtcTP9JlzziLp9IFRjjQh3xKgfblx57CmRJbqH3fT5JJ\n" +
+            "IAIDVTz3ZUcqhPTFAnNsO1oNBEyrO5X9rwCiSy7aRijY/11R75mIIvyA9zyd9ss1\n" +
+            "kvrrER0GWMTDvC84FZD2vhkXgPTFrB1Dn9f3QgO5APT9GCFY5hdpqqPEXOSdRzQo\n" +
+            "h9j4OQAqtA==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=revoked.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US
+    // Serial number: 6f1d774ad5e7b6d251d217661782bbdb6f37d
+    // Valid from: Mon Jan 28 15:34:38 PST 2019 until: Thu Apr 28 16:34:38 PDT 2022
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIE2zCCA8OgAwIBAgITBvHXdK1ee20lHSF2YXgrvbbzfTANBgkqhkiG9w0BAQsF\n" +
+            "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+            "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM0MzhaFw0yMjA0\n" +
+            "MjgyMzM0MzhaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+            "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" +
+            "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" +
+            "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" +
+            "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTFhLmFtYXpvbnRydXN0LmNvbTCCASIwDQYJ\n" +
+            "KoZIhvcNAQEBBQADggEPADCCAQoCggEBANUoHop9sW+QlgVsdtacioraTAWHcSTd\n" +
+            "MNkOkOEMgJIFPyfdcDvW/H2NvpdYeIQqzaCgT2kcsONWTZTPJMirCPnzl1ohHOZU\n" +
+            "uTnOVkamGxvNmQCURLBXmlCMRTCI5RY3CuYntFFbSPAnbumsF+K/gKqcE6ME53Bw\n" +
+            "PAwn4qwavB0i5Ib7Jk8XYzxSYXC9l8QLxt6fshPJRlecpXzfmVFvMAm3IbaLcpuv\n" +
+            "AtD+8I2KwjNtBPRPNYeFsWxwsgUGAyHEGa61oTGUqqAXu5YmPfyK+YTOJdoofsh4\n" +
+            "Tf3K7AKxnPWuvY3RNTs1pzEVwJYZqSsNwbgyKJJ4+0Xe4iP7qB8SYf8CAwEAAaOC\n" +
+            "ASkwggElMA4GA1UdDwEB/wQEAwIFoDAdBgNVHQ4EFgQUGHreoz+LP/Wr+RKzuexO\n" +
+            "V8ICtmEwHwYDVR0jBBgwFoAUYtRCXoZwdWqQvMa40k1gwjS6UTowHQYDVR0lBBYw\n" +
+            "FAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw\n" +
+            "AYYhaHR0cDovL29jc3Auc2NhMWEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC\n" +
+            "hipodHRwOi8vY3J0LnNjYTFhLmFtYXpvbnRydXN0LmNvbS9zY2ExYS5jZXIwKAYD\n" +
+            "VR0RBCEwH4IdcmV2b2tlZC5zY2ExYS5hbWF6b250cnVzdC5jb20wEwYDVR0gBAww\n" +
+            "CjAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBABSbe1UCLL7Qay6XK5wD8B5a\n" +
+            "wvR1XG3UrggpVIz/w5cutEm/yE71hzE0gag/3YPbNYEnaLbJH+9jz4YW9wd/cEPj\n" +
+            "xSK5PErAQjCd+aA4LKN1xqkSysgYknl0y47hJBXGnWf+hxvBBHeSoUzM0KIC21pC\n" +
+            "ZyXrmfaPCQAz13ruYIYdQaETqXGVORmKbf/a+Zn18/tfQt0LeeCYVoSopbXWQvcJ\n" +
+            "gUMtdIqYQmb8aVj0pdZXwKl4yZ2DtlS3Z9MpWNgQNlhRPmiYlu28y2yTtZ9SwD6m\n" +
+            "2f+cwc19aJrDT4Y280px+jRU7dIE6oZVJU+yBRVIZYpUFAB7extCMVxnTkCf8Dk=\n" +
+            "-----END CERTIFICATE-----";
+
+    public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+        // EE certificates don't have CRLDP extension
+        if (!ocspEnabled){
+            pathValidator.validate(new String[]{INT},
+                    ValidatePathWithParams.Status.GOOD, null, System.out);
+
+            return;
+        }
+
+        // Validate valid
+        pathValidator.validate(new String[]{VALID, INT},
+                ValidatePathWithParams.Status.GOOD, null, System.out);
+
+        // Validate Revoked
+        pathValidator.validate(new String[]{REVOKED, INT},
+                ValidatePathWithParams.Status.REVOKED,
+                "Mon Jan 28 15:35:56 PST 2019", System.out);
+    }
+}
+
+class AmazonCA_2 {
+
+    // Owner: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US
+    // Issuer: CN=Amazon Root CA 2, O=Amazon, C=US
+    // Serial number: 67f945755f187a91f8163f3e624620177ff38
+    // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+    private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGRzCCBC+gAwIBAgITBn+UV1Xxh6kfgWPz5iRiAXf/ODANBgkqhkiG9w0BAQwF\n" +
+            "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" +
+            "b24gUm9vdCBDQSAyMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" +
+            "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" +
+            "IDJBMQ8wDQYDVQQDEwZBbWF6b24wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\n" +
+            "AoICAQC0P8hSLewmrZ41CCPBQytZs5NBFMq5ztbnMf+kZUp9S25LPfjNW3zgC/6E\n" +
+            "qCTWNVMMHhq7ez9IQJk48qbfBTLlZkuKnUWbA9vowrDfcxUN0mRE4B/TJbveXyTf\n" +
+            "vE91iDlqDrERecE9D8sdjzURrtHTp27lZdRkXFvfEVCq4hl3sHkzjodisaQthLp1\n" +
+            "gLsiA7vKt+8zcL4Aeq52UyYb8r4/jdZ3KaQp8O/T4VwDCRKm8ey3kttpJWaflci7\n" +
+            "eRzNjY7gE3NMANVXCeQwOBfH2GjINFCObmPsqiBuoAnsv2k5aQLNoU1OZk08ClXm\n" +
+            "mEZ2rI5qZUTX1HuefBJnpMkPugFCw8afaHnB13SkLE7wxX8SZRdDIe5WiwyDL1tR\n" +
+            "2+8lpz4JsMoFopHmD3GaHyjbN+hkOqHgLltwewOsiyM0u3CZphypN2KeD+1FLjnY\n" +
+            "TgdIAd1FRgK2ZXDDrEdjnsSEfShKf0l4mFPSBs9E3U6sLmubDRXKLLLpa/dF4eKu\n" +
+            "LEKS1bXYT28iM6D5gSCnzho5G4d18jQD/slmc5XmRo5Pig0RyBwDaLuxeIZuiJ0A\n" +
+            "J6YFhffbrLYF5dEQl0cU+t3VBK5u/o1WkWXsZawU038lWn/AXerodT/pAcrtWA4E\n" +
+            "NQEN09WEKMhZVPhqdwhF/Gusr04mQtKt7T2v6UMQvtVglv5E7wIDAQABo4IBOTCC\n" +
+            "ATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYE\n" +
+            "FNpDStD8AcBLv1gnjHbNCoHzlC70MB8GA1UdIwQYMBaAFLAM8Eww9AVYAkj9M+VS\n" +
+            "r0uE42ZSMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3Au\n" +
+            "cm9vdGNhMi5hbWF6b250cnVzdC5jb20wOgYIKwYBBQUHMAKGLmh0dHA6Ly9jcnQu\n" +
+            "cm9vdGNhMi5hbWF6b250cnVzdC5jb20vcm9vdGNhMi5jZXIwPwYDVR0fBDgwNjA0\n" +
+            "oDKgMIYuaHR0cDovL2NybC5yb290Y2EyLmFtYXpvbnRydXN0LmNvbS9yb290Y2Ey\n" +
+            "LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggIBAEO5W+iF\n" +
+            "yChjDyyrmiwFupVWQ0Xy2ReFNQiZq7XKVHvsLQe01moSLnxcBxioOPBKt1KkZO7w\n" +
+            "Gcbmke0+7AxLaG/F5NPnzRtK1/pRhXQ0XdU8pVh/1/h4GoqRlZ/eN0JDarUhZPkV\n" +
+            "kSr96LUYDTxcsAidF7zkzWfmtcJg/Aw8mi14xKVEa6aVyKu54c8kKkdlt0WaigOv\n" +
+            "Z/xYhxp24AfoFKaIraDNdsD8q2N7eDYeN4WGLzNSlil+iFjzflI9mq1hTuI/ZNjV\n" +
+            "rbvob6FUQ8Cc524gMjbpZCNuZ1gfXzwwhGp0AnQF6CJsWF9uwPpZEVFnnnfiWH3M\n" +
+            "oup41EvBhqaAqOlny0sm5pI82nRUCAE3DLkJ1+eAtdQaYblZQkQrRyTuPmJEm+5y\n" +
+            "QwdDVw6uHc5OsSj/tyhh8zJ2Xq3zgh3dMONGjJEysxGaCoIb+61PWwMy2dIarVwI\n" +
+            "r+c+AY+3PrhgBspNdWZ87JzNHii7ksdjUSVGTTy1vGXgPYrv0lp0IMnKaZP58xiw\n" +
+            "rDx7uTlQuPVWNOZvCaT3ZcoxTsNKNscIUe+WJjWx5hdzpv/oksDPY5ltZ0j3hlDS\n" +
+            "D+Itk95/cNJVRM/0HpxI1SX9MTZtOSJoEDdUtOpVaOuBAvEK4gvTzdt0r5L+fuI6\n" +
+            "o5LAuRo/LO1xVRH49KFRoaznzU3Ch9+kbPb3\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=good.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    // Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US
+    // Serial number: 703e4e70616c90d611fd04a5ecc635665184e
+    // Valid from: Mon Jul 29 16:54:06 PDT 2019 until: Sat Aug 29 16:54:06 PDT 2020
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIHEzCCBPugAwIBAgITBwPk5wYWyQ1hH9BKXsxjVmUYTjANBgkqhkiG9w0BAQwF\n" +
+            "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+            "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0MDZaFw0yMDA4\n" +
+            "MjkyMzU0MDZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+            "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" +
+            "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" +
+            "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" +
+            "czEjMCEGA1UEAxMaZ29vZC5zY2EyYS5hbWF6b250cnVzdC5jb20wggIiMA0GCSqG\n" +
+            "SIb3DQEBAQUAA4ICDwAwggIKAoICAQC+XjOB3ZCFX+b9y9reP+e6EAQz4ytiMSqU\n" +
+            "O4s5MyYLkY6n4BIZHmgWeQ2IgW1VrH8ho+Iu3UsTiuhd3/L/q/w+T0OJfcrWngTs\n" +
+            "uVcIuvUr32ObPeeWbg/m/lkN7hqH1jY62iybYVrFXiLo1+0G92PUazcyNvyA20+G\n" +
+            "HsvGG5jlArWNgRLdc8KUXxvnDUxx5vu4jeHEZnqSwuulV1h9ve0UutkmoK0Sk7Rz\n" +
+            "HMxYK0LmUT5OvcNQSkUi5nLi+M1FxnYYgsELwSiKSSEDfEdgxooMAiVTgw51Q/DB\n" +
+            "lTOjAIDL3K3J0yGfIG3bwLvE1qz2Z5yWn8f3JibIah7LrC4PiZDDLHFM6V9l+YqU\n" +
+            "RqimJ5BltSyAx7bxQNZ1AW3Lxvvm894i4k6/Vdf1CDovRuTMPCDAQmKA/A/AQ7TN\n" +
+            "q3bBimX6UyuJu0I8RyvAYKzFhOOqe4vXrbndTbje/jnzTNQPeIIcuRa9cgXTOrbw\n" +
+            "86FTUKj6AZXihRWjKWsQpDwdgE0tQETZ3ynCXfbBKfFmn0MSjeX0CEEAZdYHR8EV\n" +
+            "F271Yt7UJjS/FP702aHTOWk7zFbIRfFQODvBhn0I8p/Stk2sDq4/YsbXVZOe3+ad\n" +
+            "YavoiODGSAH6ZcZzULumgK9eii0koAOPB/xqXnkcTS63gEHOKjLQl3hqdVZRCugv\n" +
+            "1CwUXLvoSwIDAQABo4IBYzCCAV8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdDgQWBBTa\n" +
+            "j6dHgPdOxTGLcwaNDeaMnlSxNjAfBgNVHSMEGDAWgBTaQ0rQ/AHAS79YJ4x2zQqB\n" +
+            "85Qu9DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYIKwYBBQUHAQEE\n" +
+            "aTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5zY2EyYS5hbWF6b250cnVzdC5j\n" +
+            "b20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2NhMmEuYW1hem9udHJ1c3QuY29t\n" +
+            "L3NjYTJhLmNlcjAlBgNVHREEHjAcghpnb29kLnNjYTJhLmFtYXpvbnRydXN0LmNv\n" +
+            "bTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYGBWeBDAEBMC0wKwYIKwYBBQUH\n" +
+            "AgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNvbS9jcHMwDQYJKoZIhvcNAQEM\n" +
+            "BQADggIBAE6RwZAZvN0i9ygwzqoX9DhSPtvZ3xIO0G0Bhgjkb986+p8XJstU3gEM\n" +
+            "8P2i1J/YthXCnRGedm+Odxx+31G6xIYfP5S5g7HyRGkj/aXNXy4s3KjH8HJgOY9N\n" +
+            "ra3XfC05OKq5FpyZQDZ+hxCdLrH3Gs+UxREbu+LuIKUpI7nMVEjn9XynKyOdKN21\n" +
+            "Kq5VsuI0fDWCYvUN1M+lI/LgE5HbNJVQJs+dB7g1/kaOeaLia7Wk1ys+uRzB58rp\n" +
+            "FKAoLk++HWTfNDkbN8vKRfHhJ/xhI9ju3TWcci6EyFVAym1C62UkJNI0KHgQ+zc7\n" +
+            "nl1tv/ytj8N/eJoysyp23lJ5qrVetlQORfgXryGkWBMYBvYF8zbBb/f+UXHDKVWt\n" +
+            "9l1lL6HQGY/tTo253pj6/FgDD35bZdjLQeUVmbnz679S5oUmoH5ZtSdnpUTghU3p\n" +
+            "bae9adBFY9S1pm50Q3ckRVBAwNqNmI0KKUh14Ms8KSAUHg19NvGsBonqwOT2rdbv\n" +
+            "xZ47N6c2eCl/cjMvzre0v0NoUO+3og2GHeAoOwVos6480YDbMqp739tOFPxBcsII\n" +
+            "6SjpDVh+14dkSW6kEKeaCFLR+eChqutri1VQbQ49nmADQWw9Al8vBytSnPv0YN6W\n" +
+            "XfIE1Qj7YmHu/UuoeKVsqDqoP/no29+96dtfd4afJqlIoyZUqXpt\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=revoked.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    //Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US
+    //Serial number: 6f1d782c0aa2f4866b7b522c279b939b92369
+    //Valid from: Mon Jan 28 15:37:45 PST 2019 until: Thu Apr 28 16:37:45 PDT 2022
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIG2zCCBMOgAwIBAgITBvHXgsCqL0hmt7Uiwnm5ObkjaTANBgkqhkiG9w0BAQwF\n" +
+            "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+            "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM3NDVaFw0yMjA0\n" +
+            "MjgyMzM3NDVaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+            "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" +
+            "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" +
+            "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" +
+            "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTJhLmFtYXpvbnRydXN0LmNvbTCCAiIwDQYJ\n" +
+            "KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKFm418X8hN1YTgD2XpMb4sp78mw8k3j\n" +
+            "Dq/vnpX48evVUzNpHpy4qRz/ZHBR4HUJO4lhfnX+CO0uRqqqx4F0JZRQB3KevaU8\n" +
+            "QGWHdJGhEddnurDhrgOUa+ZroqUnMCsTJfbyGtC6aiEXeu/eMhEUFkuBxJH1JtwD\n" +
+            "dQXMXuMjG07SVjOkhTkbMDzA/YbUqkDeOIybifDuvA5LEsl+kReY0b6RYFo2Tt/M\n" +
+            "dPhJD8q3Wsu+XCiCnbpcwlEVGxiD2RVRXJJ9o3ALGOxqU69V+lYS0kkwNHT7oV9J\n" +
+            "rhgt7iOCq0aoTAxu2j4FCp0JHNhGoW9pXoMXnmS6kK80hzLNYDxvKEaVaKkiYHw5\n" +
+            "CV0Vwii05ICa14nrStH/jcRNLyU+gp+6OeerPV3jpKWshGKWewF+2UiWU2WHTSrd\n" +
+            "Wis0/qEfFK/kSraAxpd+KavEEavKeudoMAHIxMACOk9E/fF5zhd2y4G1q1BdoRlR\n" +
+            "KP4GIV2v6qH6Ru2mNSuge9il6kDXxFNucrYKLDbAqkqalohkvDavcPoG9gZT3etv\n" +
+            "4IcgJriIWRxbJwKPpwJM+6wa6RpwoeJMuEp3ZBP7KDaQ8YX4rlf4zXLAsOKCNA9K\n" +
+            "OS/qYQ/I4g0E1WhfgEKClaLPS2u7jeVR6s1t4txGo4vq5Dkt17KTCew/WsX3rckf\n" +
+            "a2p5zvFcfpCNAgMBAAGjggEpMIIBJTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYE\n" +
+            "FAF8N1wV8EoYFkMXH6tEnmR/7vI+MB8GA1UdIwQYMBaAFNpDStD8AcBLv1gnjHbN\n" +
+            "CoHzlC70MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcB\n" +
+            "AQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTJhLmFtYXpvbnRydXN0\n" +
+            "LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2EyYS5hbWF6b250cnVzdC5j\n" +
+            "b20vc2NhMmEuY2VyMCgGA1UdEQQhMB+CHXJldm9rZWQuc2NhMmEuYW1hem9udHJ1\n" +
+            "c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBDAUAA4ICAQBC\n" +
+            "VwR1NFk1IYIF4cjU7ML1aj8OIn+8mtakGQnuSJLK6ypSysINJBS48ZDdP6XZXvyD\n" +
+            "iTS0xEAPjAZHTqrABdNYmvJeL2RnN99DIwVzBpZp4NLTXbiSW7jb0Y5cEPDGJMOo\n" +
+            "SUAAM6fsiPRfz5vX4XVPznbcF2AwE/NVV+L3n9LVRt7qv2VqIEvLioR56Dq+5ofR\n" +
+            "4bw0BVlEYWF4Gsy7WDDTL1iLNBUwZTqBHwTv0fgDRiPqb/odmLQuRANwcJy8B8Zr\n" +
+            "s/yX4SeESaRdA82lAlQilksQitXS2qvQN06GEDOgUxYE6EabFdgklV5JypKqdOly\n" +
+            "vzpaDpF3z5W8Bj3D4fns1Kjrh1pPh5JRvg+616diKnQRt4X5q+EtmnXhDvIGMISI\n" +
+            "FuGwj57CNQ2x2MY2HHKWPrOccpQfEEvoSNR+ntYWrtSSttZq948O+zZBk1TXWuXV\n" +
+            "TVXllqTg8lp6d5cfKgvtHKgt98WkpPOcLVrNuVnMAIfDw6ar54dVKqrvkeEcF6mJ\n" +
+            "7oMKjJX/Vu9lYoGViBIfdeqcCPWSI8BpnCKaG7dTQO3Q1ObGmLdGBRlsRh+d+S5l\n" +
+            "Fq326ckbjx537e5/ai31lOR7OwVh9TDweKLqIACjs987C0EJSEfoOue25WRww2va\n" +
+            "iX9SrTPm4GxQ2OJgYwx0+HbezJXFN+dhaOFUavTSFw==\n" +
+            "-----END CERTIFICATE-----";
+
+    public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+        // EE certificates don't have CRLDP extension
+        if (!ocspEnabled){
+            pathValidator.validate(new String[]{INT},
+                    ValidatePathWithParams.Status.GOOD, null, System.out);
+
+            return;
+        }
+
+        // Validate valid
+        pathValidator.validate(new String[]{VALID, INT},
+                ValidatePathWithParams.Status.GOOD, null, System.out);
+
+        // Validate Revoked
+        pathValidator.validate(new String[]{REVOKED, INT},
+                ValidatePathWithParams.Status.REVOKED,
+                "Mon Jan 28 15:38:57 PST 2019", System.out);
+    }
+}
+
+class AmazonCA_3 {
+
+    // Owner: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US
+    // Issuer: CN=Amazon Root CA 3, O=Amazon, C=US
+    // Serial number: 67f945758fe55b9ee3f75831d47f07d226c8a
+    // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+    private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+            "MIICuzCCAmGgAwIBAgITBn+UV1j+VbnuP3WDHUfwfSJsijAKBggqhkjOPQQDAjA5\n" +
+            "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" +
+            "Um9vdCBDQSAzMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" +
+            "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDNB\n" +
+            "MQ8wDQYDVQQDEwZBbWF6b24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATYcYsK\n" +
+            "mYdR0Gj8Xz45E/lfcTTnXhg2EtAIYBIHyXv/ZQyyyCas1aptX/I5T1coT6XK181g\n" +
+            "nB8hADuKfWlNoIYRo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8B\n" +
+            "Af8EBAMCAYYwHQYDVR0OBBYEFATc4JXl6LlrlKHvjFsxHhN+VZfaMB8GA1UdIwQY\n" +
+            "MBaAFKu229cGnjesMIYHkXDHnMQZsXjAMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEF\n" +
+            "BQcwAYYjaHR0cDovL29jc3Aucm9vdGNhMy5hbWF6b250cnVzdC5jb20wOgYIKwYB\n" +
+            "BQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNh\n" +
+            "My5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2EzLmFtYXpv\n" +
+            "bnRydXN0LmNvbS9yb290Y2EzLmNybDARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZI\n" +
+            "zj0EAwIDSAAwRQIgOl/vux0qfxNm05W3eofa9lKwz6oKvdu6g6Sc0UlwgRcCIQCS\n" +
+            "WSQ6F6JHLoeOWLyFFF658eNKEKbkEGMHz34gLX/N3g==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=good.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US
+    // Serial number: 703e4e9bbc2605f37967a0e95f31f4789a677
+    // Valid from: Mon Jul 29 16:54:43 PDT 2019 until: Sat Aug 29 16:54:43 PDT 2020
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIDhzCCAy2gAwIBAgITBwPk6bvCYF83lnoOlfMfR4mmdzAKBggqhkjOPQQDAjBG\n" +
+            "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+            "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0NDNaFw0yMDA4Mjky\n" +
+            "MzU0NDNaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+            "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" +
+            "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" +
+            "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" +
+            "MCEGA1UEAxMaZ29vZC5zY2EzYS5hbWF6b250cnVzdC5jb20wWTATBgcqhkjOPQIB\n" +
+            "BggqhkjOPQMBBwNCAARl4yxf8XcvWR0LZ+YuBC0CpkwtU2NiMdlIM7eX0lxhQp53\n" +
+            "NpLlCrPRNzOWrjCJDdn21D0u7PrtN94UHLHOg9X0o4IBYzCCAV8wDgYDVR0PAQH/\n" +
+            "BAQDAgeAMB0GA1UdDgQWBBT2cHmOJFLWfg1Op7xAdAnqYcwaPzAfBgNVHSMEGDAW\n" +
+            "gBQE3OCV5ei5a5Sh74xbMR4TflWX2jAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" +
+            "BQUHAwIwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5z\n" +
+            "Y2EzYS5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2Nh\n" +
+            "M2EuYW1hem9udHJ1c3QuY29tL3NjYTNhLmNlcjAlBgNVHREEHjAcghpnb29kLnNj\n" +
+            "YTNhLmFtYXpvbnRydXN0LmNvbTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYG\n" +
+            "BWeBDAEBMC0wKwYIKwYBBQUHAgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNv\n" +
+            "bS9jcHMwCgYIKoZIzj0EAwIDSAAwRQIgURdcqJVr4PWNIkmWcSKmzgZ1i94hQpGe\n" +
+            "mWbE9osk4m0CIQDhxIguihwvDa5RsBwdM0aRDgGKLNHigGqJoKqgH0d2qg==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=revoked.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US
+    // Serial number: 6f1d78cf0ca64ce7f551a6f2a0715cc0e8b50
+    // Valid from: Mon Jan 28 15:40:01 PST 2019 until: Thu Apr 28 16:40:01 PDT 2022
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIDTzCCAvWgAwIBAgITBvHXjPDKZM5/VRpvKgcVzA6LUDAKBggqhkjOPQQDAjBG\n" +
+            "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+            "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQwMDFaFw0yMjA0Mjgy\n" +
+            "MzQwMDFaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+            "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" +
+            "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" +
+            "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" +
+            "JAYDVQQDEx1yZXZva2VkLnNjYTNhLmFtYXpvbnRydXN0LmNvbTBZMBMGByqGSM49\n" +
+            "AgEGCCqGSM49AwEHA0IABJNl90Jq0wddpFj+JbLtmvGR/1geL5t1tvV406jGpYn2\n" +
+            "C5lAFjwASFy7pAnazZbfSkIDUU2i2XU0+7Cs+j1S/EOjggEpMIIBJTAOBgNVHQ8B\n" +
+            "Af8EBAMCB4AwHQYDVR0OBBYEFPhX3dYays5Sps0xTgouLkZzYLg4MB8GA1UdIwQY\n" +
+            "MBaAFATc4JXl6LlrlKHvjFsxHhN+VZfaMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr\n" +
+            "BgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3Nw\n" +
+            "LnNjYTNhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5z\n" +
+            "Y2EzYS5hbWF6b250cnVzdC5jb20vc2NhM2EuY2VyMCgGA1UdEQQhMB+CHXJldm9r\n" +
+            "ZWQuc2NhM2EuYW1hem9udHJ1c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMAoG\n" +
+            "CCqGSM49BAMCA0gAMEUCICLb16/50S4fOAFafi5lagdx7q6EDPPm596g19eQDMXk\n" +
+            "AiEAksCMLypRB4t30FABlsEjhVCBIxay0iIer2OcCIrhfEI=\n" +
+            "-----END CERTIFICATE-----";
+
+    public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+        // EE certificates don't have CRLDP extension
+        if (!ocspEnabled){
+            pathValidator.validate(new String[]{INT},
+                    ValidatePathWithParams.Status.GOOD, null, System.out);
+
+            return;
+        }
+
+        // Validate valid
+        pathValidator.validate(new String[]{VALID, INT},
+                ValidatePathWithParams.Status.GOOD, null, System.out);
+
+        // Validate Revoked
+        pathValidator.validate(new String[]{REVOKED, INT},
+                ValidatePathWithParams.Status.REVOKED,
+                "Mon Jan 28 15:40:35 PST 2019", System.out);
+    }
+}
+
+class AmazonCA_4 {
+
+    // Owner: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US
+    // Issuer: CN=Amazon Root CA 4, O=Amazon, C=US
+    // Serial number: 67f94575a8862a9072e3239c37ceba1274e18
+    // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+    private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIC+TCCAn6gAwIBAgITBn+UV1qIYqkHLjI5w3zroSdOGDAKBggqhkjOPQQDAzA5\n" +
+            "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" +
+            "Um9vdCBDQSA0MB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" +
+            "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDRB\n" +
+            "MQ8wDQYDVQQDEwZBbWF6b24wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASRP0kIW0Ha\n" +
+            "7+ORvEVhIS5gIgkH66X5W9vBRTX14oG/1elIyI6LbFZ+E5KAufL0XoWJGI1WbPRm\n" +
+            "HW246FKSzF0wOEZZyxEROz6tuaVsnXRHRE76roS/Wr064uJpKH+Lv+SjggE5MIIB\n" +
+            "NTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU\n" +
+            "pSHN2+tTIZmqytlnQpQlsnv0wuMwHwYDVR0jBBgwFoAU0+zHOmVuzOHadppW+5zz\n" +
+            "hm1X5YEwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5y\n" +
+            "b290Y2E0LmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5y\n" +
+            "b290Y2E0LmFtYXpvbnRydXN0LmNvbS9yb290Y2E0LmNlcjA/BgNVHR8EODA2MDSg\n" +
+            "MqAwhi5odHRwOi8vY3JsLnJvb3RjYTQuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTQu\n" +
+            "Y3JsMBEGA1UdIAQKMAgwBgYEVR0gADAKBggqhkjOPQQDAwNpADBmAjEA59RAOBaj\n" +
+            "uh0rT/OOTWPEv6TBnb9XEadburBaXb8SSrR8il+NdkfS9WXRAzbwrG7LAjEA3ukD\n" +
+            "1HrQq+WXHBM5sIuViJI/Zh7MOjsc159Q+dn36PBqLRq03AXqE/lRjnv8C5nj\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=good.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US
+    // Serial number: 703e4ec57c72d5669efbc98875c3f6bc3f934
+    // Valid from: Mon Jul 29 16:55:17 PDT 2019 until: Sat Aug 29 16:55:17 PDT 2020
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIDxTCCA0qgAwIBAgITBwPk7FfHLVZp77yYh1w/a8P5NDAKBggqhkjOPQQDAzBG\n" +
+            "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+            "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU1MTdaFw0yMDA4Mjky\n" +
+            "MzU1MTdaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+            "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" +
+            "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" +
+            "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" +
+            "MCEGA1UEAxMaZ29vZC5zY2E0YS5hbWF6b250cnVzdC5jb20wdjAQBgcqhkjOPQIB\n" +
+            "BgUrgQQAIgNiAAS9fqMYfOBsdXMSsPjqOlTgIGOlOQWA7Wg6XwVvHTr0+UN+XTeC\n" +
+            "yZN+XjLbEDQ0CF5eryRZ535sDpwh3qNe0lYFO1n1+2iDtDI1jhhLNYNxBpVnR2BU\n" +
+            "2l9EuRmgRbQpDCajggFjMIIBXzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFMd0\n" +
+            "itH5IcE6DpM1uTSBV/6DLmK7MB8GA1UdIwQYMBaAFKUhzdvrUyGZqsrZZ0KUJbJ7\n" +
+            "9MLjMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRp\n" +
+            "MGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTRhLmFtYXpvbnRydXN0LmNv\n" +
+            "bTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2E0YS5hbWF6b250cnVzdC5jb20v\n" +
+            "c2NhNGEuY2VyMCUGA1UdEQQeMByCGmdvb2Quc2NhNGEuYW1hem9udHJ1c3QuY29t\n" +
+            "MFAGA1UdIARJMEcwDQYLYIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcC\n" +
+            "ARYfaHR0cHM6Ly93d3cuYW1hem9udHJ1c3QuY29tL2NwczAKBggqhkjOPQQDAwNp\n" +
+            "ADBmAjEA2RBD1F+rnm394VkqA3ncysM3deoyfWqaoAO5923MNisswPnHfVqnfeXf\n" +
+            "ZwTAvVTBAjEAiiaPx9GRjEk8IBKvCSbTp9rPogVTN7zDDQGrwA83O0pRP7A0dxtT\n" +
+            "pn/0K5Sj8otp\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=revoked.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+    // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+    // OID.1.3.6.1.4.1.311.60.2.1.3=US
+    // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US
+    // Serial number: 6f1d79295c384a699d51c2d756bd46213b5b3
+    // Valid from: Mon Jan 28 15:41:16 PST 2019 until: Thu Apr 28 16:41:16 PDT 2022
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIDjTCCAxKgAwIBAgITBvHXkpXDhKaZ1RwtdWvUYhO1szAKBggqhkjOPQQDAzBG\n" +
+            "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+            "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQxMTZaFw0yMjA0Mjgy\n" +
+            "MzQxMTZaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+            "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" +
+            "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" +
+            "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" +
+            "JAYDVQQDEx1yZXZva2VkLnNjYTRhLmFtYXpvbnRydXN0LmNvbTB2MBAGByqGSM49\n" +
+            "AgEGBSuBBAAiA2IABLuNpZTcNU3FElNP3Y/OeXIZcIMXkFTBi/n92fNwHfqUbEhH\n" +
+            "H+PovJ26eAGvb5a8bGc275MBFcVnWL0rCVgM+j9KAtBDCRJX3f7mo0D2VKcmtZKu\n" +
+            "jPxwGPy2kuqM505dGqOCASkwggElMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQU\n" +
+            "zUFIhn+hphzCKA2qgAdLztSBzJgwHwYDVR0jBBgwFoAUpSHN2+tTIZmqytlnQpQl\n" +
+            "snv0wuMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEB\n" +
+            "BGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3Auc2NhNGEuYW1hem9udHJ1c3Qu\n" +
+            "Y29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnNjYTRhLmFtYXpvbnRydXN0LmNv\n" +
+            "bS9zY2E0YS5jZXIwKAYDVR0RBCEwH4IdcmV2b2tlZC5zY2E0YS5hbWF6b250cnVz\n" +
+            "dC5jb20wEwYDVR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwMDaQAwZgIxALDA\n" +
+            "klY3iKwyzwpwVtLfLxzQEl45xvE2VjBJvfJJ60KhJt7Ud0gt0zxkogh29+mpEQIx\n" +
+            "ANTG1mk8OJB41DU7ru1Pwc6ju8STw1FdwDp/Eliqhvnm2i0k4/F1bBHLta2mlC2V\n" +
+            "hg==\n" +
+            "-----END CERTIFICATE-----";
+
+    public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+        // EE certificates don't have CRLDP extension
+        if (!ocspEnabled){
+            pathValidator.validate(new String[]{INT},
+                    ValidatePathWithParams.Status.GOOD, null, System.out);
+
+            return;
+        }
+
+        // Validate valid
+        pathValidator.validate(new String[]{VALID, INT},
+                ValidatePathWithParams.Status.GOOD, null, System.out);
+
+        // Validate Revoked
+        pathValidator.validate(new String[]{REVOKED, INT},
+                ValidatePathWithParams.Status.REVOKED,
+                "Mon Jan 28 15:41:53 PST 2019", System.out);
+    }
+}
diff --git a/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java b/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java
index e3edae4..3b34661 100644
--- a/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java
+++ b/test/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java
@@ -23,7 +23,7 @@
 
  /*
  * @test
- * @bug 8189131
+ * @bug 8189131 8231887
  * @summary Interoperability tests with Comodo RSA, ECC, userTrust RSA, and
  *          userTrust ECC CAs
  * @build ValidatePathWithParams
@@ -112,13 +112,66 @@
 
     // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
     // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: a0c7cabcc25ed9358ded02cc1d485545
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIH0TCCBrmgAwIBAgIRAKDHyrzCXtk1je0CzB1IVUUwDQYJKoZIhvcNAQELBQAw\n" +
+            "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" +
+            "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" +
+            "VQQDEy9DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" +
+            "ciBDQTAeFw0xOTA5MzAwMDAwMDBaFw0yMTEyMjgyMzU5NTlaMIIBPjERMA8GA1UE\n" +
+            "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" +
+            "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRAw\n" +
+            "DgYDVQQHEwdTYWxmb3JkMRYwFAYDVQQJEw1UcmFmZm9yZCBSb2FkMRYwFAYDVQQJ\n" +
+            "Ew1FeGNoYW5nZSBRdWF5MSUwIwYDVQQJExwzcmQgRmxvb3IsIDI2IE9mZmljZSBW\n" +
+            "aWxsYWdlMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxGjAYBgNVBAsTEUNPTU9E\n" +
+            "TyBFViBTR0MgU1NMMTgwNgYDVQQDEy9jb21vZG9yc2FjZXJ0aWZpY2F0aW9uYXV0\n" +
+            "aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n" +
+            "AQoCggEBAND/eZQBTjpBDsuteKwl+zpTitF8tJzwHAhcQHC2AaLF/GJl1rnjx4Of\n" +
+            "elMhKhN1Od9KU6onHGOd2w4mD4EiYK9TpXwuwTyzfkCmnkqxZjYK3KAJN013o4L+\n" +
+            "8y1zsGVUulpN/GfMaxTb4XdmeSekTP91Phw3xezijBq3sa++1rO5RBaT1IHeHhHv\n" +
+            "iC9WNrG8CIg/j5MyC9i43LZHiRXLER1LzT/MCIRsiG5AEbiYXV5BNd5SiiHtBJ1q\n" +
+            "0ZJH+AxL2ERaT41VCppboZwThmJGGoky9FWjp6z8U6Enx0fAMJIZNEzW6LAJFKPE\n" +
+            "ynEU004jFFCEumPUqqCC4ogxulphY80CAwEAAaOCA3EwggNtMB8GA1UdIwQYMBaA\n" +
+            "FDna/8ooFIqodBMIueQOqdL6fp1pMB0GA1UdDgQWBBQ+S4ZhIrwOoeGs9BBT4uXq\n" +
+            "89Ux/jAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggr\n" +
+            "BgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA7BgwrBgEEAbIxAQIBBQEwKzAp\n" +
+            "BggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwBwYFZ4EM\n" +
+            "AQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09N\n" +
+            "T0RPUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGHBggr\n" +
+            "BgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2EuY29t\n" +
+            "L0NPTU9ET1JTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAk\n" +
+            "BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMDoGA1UdEQQzMDGC\n" +
+            "L2NvbW9kb3JzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29t\n" +
+            "MIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdQDuS723dc5guuFCaR+r4Z5mow9+\n" +
+            "X7By2IMAxHuJeqj9ywAAAW2DAXefAAAEAwBGMEQCIDqP1einOiPHnaG1fOZMDrEc\n" +
+            "RAxjq3vEl94fp4pkmke7AiBsJOvPE6irgcOO1/lnP7NRuln7iPJjU7T20PEK5/rm\n" +
+            "KwB2AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYMBd0kAAAQD\n" +
+            "AEcwRQIhALgUI5XxM1NHbJDdr19h2pe3LhzK4tpuB/OQ9BgCyrGXAiBdr6mNCB/G\n" +
+            "rbdVx0u7iezwC7mq7iaWugR3rrWlSA8fWQB2ALvZ37wfinG1k5Qjl6qSe0c4V5UK\n" +
+            "q1LoGpCWZDaOHtGFAAABbYMBd1oAAAQDAEcwRQIgXbG32dagMeLhuZb+LSpJO1vI\n" +
+            "BmxmRnNdiz5FbG9cCbwCIQCr1X9f+ebT5fhlDUNBURUorTtM8QQciBiueBqvHk7+\n" +
+            "1DANBgkqhkiG9w0BAQsFAAOCAQEAM/A/1dgoc5NP1n+w3SX9qWcN7QT7ExdrnZSl\n" +
+            "Ygn0PF2fx4gz7cvNKucbpQJNA4C9awGydyYK8/o5KDUXt3K7eb1OAZ/NZBjygsJs\n" +
+            "ikXvxlBh8oEoqBOfOtr24l0NGUWnP8Qeu/VPcIMER4V8qX+in0pCXkSd67nkp6Bs\n" +
+            "EcqhDPgmzdSC1gQHsZuBdotG14OfdH1cG1bRK6GadISLG1h8BFukVem42B149v8F\n" +
+            "MCIUQAYprAVv2WlTZKBx9XzuK6IK3+klHZ07Jfvjvt7PPG5HKSMWBMnMaTHKcyQI\n" +
+            "G3t91yw7BnNNInZlBSsFtqjbHhDcr7uruZdbi0rerSsi2qDr0w==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
     // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
     // ST=Greater Manchester, C=GB
     // Serial number: d3df2597cbed1ab6e02ee82021771614
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIH7jCCBtagAwIBAgIRANPfJZfL7Rq24C7oICF3FhQwDQYJKoZIhvcNAQELBQAw\n" +
             "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" +
             "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" +
@@ -164,60 +217,6 @@
             "YrTYerPngjPbZB0bfLOja0vb\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
-    // ST=Greater Manchester, C=GB
-    // Serial number: 720aa2cfa40094521224f901a984b167
-    // Valid from: Thu Jun 29 17:00:00 PDT 2017 until: Sun Sep 29 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIH8jCCBtqgAwIBAgIQcgqiz6QAlFISJPkBqYSxZzANBgkqhkiG9w0BAQsFADCB\n" +
-            "kjELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" +
-            "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNV\n" +
-            "BAMTL0NPTU9ETyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy\n" +
-            "IENBMB4XDTE3MDYzMDAwMDAwMFoXDTE5MDkyOTIzNTk1OVowggFdMREwDwYDVQQF\n" +
-            "EwgwNDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0\n" +
-            "ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExGzAZ\n" +
-            "BgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEWMBQG\n" +
-            "A1UECRMNVHJhZmZvcmQgUm9hZDEWMBQGA1UECRMNRXhjaGFuZ2UgUXVheTElMCMG\n" +
-            "A1UECRMcM3JkIEZsb29yLCAyNiBPZmZpY2UgVmlsbGFnZTEaMBgGA1UEChMRQ09N\n" +
-            "T0RPIENBIExpbWl0ZWQxGjAYBgNVBAsTEUNPTU9ETyBFViBTR0MgU1NMMTgwNgYD\n" +
-            "VQQDEy9jb21vZG9yc2FjZXJ0aWZpY2F0aW9uYXV0aG9yaXR5LWV2LmNvbW9kb2Nh\n" +
-            "LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAND/eZQBTjpBDsut\n" +
-            "eKwl+zpTitF8tJzwHAhcQHC2AaLF/GJl1rnjx4OfelMhKhN1Od9KU6onHGOd2w4m\n" +
-            "D4EiYK9TpXwuwTyzfkCmnkqxZjYK3KAJN013o4L+8y1zsGVUulpN/GfMaxTb4Xdm\n" +
-            "eSekTP91Phw3xezijBq3sa++1rO5RBaT1IHeHhHviC9WNrG8CIg/j5MyC9i43LZH\n" +
-            "iRXLER1LzT/MCIRsiG5AEbiYXV5BNd5SiiHtBJ1q0ZJH+AxL2ERaT41VCppboZwT\n" +
-            "hmJGGoky9FWjp6z8U6Enx0fAMJIZNEzW6LAJFKPEynEU004jFFCEumPUqqCC4ogx\n" +
-            "ulphY80CAwEAAaOCA3QwggNwMB8GA1UdIwQYMBaAFDna/8ooFIqodBMIueQOqdL6\n" +
-            "fp1pMB0GA1UdDgQWBBQ+S4ZhIrwOoeGs9BBT4uXq89Ux/jAOBgNVHQ8BAf8EBAMC\n" +
-            "BaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\n" +
-            "TwYDVR0gBEgwRjA7BgwrBgEEAbIxAQIBBQEwKzApBggrBgEFBQcCARYdaHR0cHM6\n" +
-            "Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmg\n" +
-            "R4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBRXh0ZW5kZWRWYWxp\n" +
-            "ZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGHBggrBgEFBQcBAQR7MHkwUQYIKwYB\n" +
-            "BQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUV4dGVuZGVk\n" +
-            "VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDov\n" +
-            "L29jc3AuY29tb2RvY2EuY29tMDoGA1UdEQQzMDGCL2NvbW9kb3JzYWNlcnRpZmlj\n" +
-            "YXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMIIBgAYKKwYBBAHWeQIEAgSC\n" +
-            "AXAEggFsAWoAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAVz5\n" +
-            "cV7GAAAEAwBHMEUCIQCpgc0Eqw3g4pr+oX88h5xgL1VEAiDpqAhbRtilgYwBbgIg\n" +
-            "UaIm+n8AHi55nB//Sb4Nz18GYVcfELfpIzRh1vW9HbYAdwBWFAaaL9fC7NP14b1E\n" +
-            "sj7HRna5vJkRXMDvlJhV1onQ3QAAAVz5cVybAAAEAwBIMEYCIQDdsgC4KZ++OP44\n" +
-            "X7LbUcNaxe0kFzbctF2L3bnmhp9nXQIhAM0/g+PrZBIBpYlOtzidePi8bBHrLWn2\n" +
-            "uBiP3pYIntl4AHcA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFc\n" +
-            "+XFeoQAABAMASDBGAiEAoySTb/QKw7JwtZtPHnECEMzgENQSFy58Kl+Mvcd3SmcC\n" +
-            "IQD8cU66Ih3ejvt0OTX+lfxQPKyggQfm4Uk/lwn5LEJXbDANBgkqhkiG9w0BAQsF\n" +
-            "AAOCAQEAKEaSYWn3Hi8rfJS4cMTJoMkVp2vpPH2dGXySBEy67TEGRw9+f75w3q95\n" +
-            "r1m3P+xsR6dBoidTq/6wqUYI51lB4Fq9ylh1Stp5Gj54CuyT+S31l7lD7sl0KMsn\n" +
-            "HDUDQHId7hKeORYpiIZOcrKOglKdi1uiGwDgoiLKh98lUrZA6durrhH+sl69wqp2\n" +
-            "0XAu+3hurXzCoZFJfyngTO1kt9qcFUAxc5LofIa9QvC6VR7dI4aAh7dUpIRlnjG3\n" +
-            "jJ1mUMTqWO6TFTtddb+uQjDqNgkYYYNuSax1WMEIZWbIi13EjXK1GPQUXJe6gQin\n" +
-            "NUq9JH9NPK6m8A1YKT+wgzfTDeaV2Q==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
         pathValidator.validate(new String[]{VALID, INT},
@@ -226,7 +225,7 @@
         // Validate Revoked
         pathValidator.validate(new String[]{REVOKED, INT},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 08:41:09 PST 2018", System.out);
+                "Wed Oct 02 06:06:24 PDT 2019", System.out);
     }
 }
 
@@ -263,13 +262,58 @@
 
     // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=Sectigo Limited,
     // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: 7972d9d8472a2d52ad1ee6edfb16cbe1
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGPzCCBeWgAwIBAgIQeXLZ2EcqLVKtHubt+xbL4TAKBggqhkjOPQQDAjCBkjEL\n" +
+            "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" +
+            "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" +
+            "L0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" +
+            "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggE6MREwDwYDVQQFEwgw\n" +
+            "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" +
+            "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" +
+            "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" +
+            "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" +
+            "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEWMBQGA1UECxMNQ09NT0RPIEVW\n" +
+            "IFNTTDE4MDYGA1UEAxMvY29tb2RvZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1l\n" +
+            "di5jb21vZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS3bqoFLtNG\n" +
+            "7/J9H5GKosDNbYL5SykVmU5FzgSEt81gyAWShkqMSfAnO50fpr65E+o86E+BR3o8\n" +
+            "V9FAU5wuOaGBo4IDcDCCA2wwHwYDVR0jBBgwFoAU007DGbpYWdEcYLdhU0c7p3eP\n" +
+            "+IowHQYDVR0OBBYEFOlnS3MqxwXDpne8IQMXMZHlVKRXMA4GA1UdDwEB/wQEAwIF\n" +
+            "gDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBP\n" +
+            "BgNVHSAESDBGMDsGDCsGAQQBsjEBAgEFATArMCkGCCsGAQUFBwIBFh1odHRwczov\n" +
+            "L3NlY3VyZS5jb21vZG8uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBH\n" +
+            "hkVodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9FQ0NFeHRlbmRlZFZhbGlk\n" +
+            "YXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYcGCCsGAQUFBwEBBHsweTBRBggrBgEF\n" +
+            "BQcwAoZFaHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRW\n" +
+            "YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8v\n" +
+            "b2NzcC5jb21vZG9jYS5jb20wOgYDVR0RBDMwMYIvY29tb2RvZWNjY2VydGlmaWNh\n" +
+            "dGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF8BgorBgEEAdZ5AgQCBIIB\n" +
+            "bASCAWgBZgB1AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABbYME\n" +
+            "EzgAAAQDAEYwRAIgbdo71lBleuJiq+D0ZLp51oVUyWD9EyrtgBSCNwIW4cMCIAqg\n" +
+            "0VFTWHEmAVjaV23fGj3Ybu3mpSiHr6viGlgA2lYaAHUAVYHUwhaQNgFK6gubVzxT\n" +
+            "8MDkOHhwJQgXL6OqHQcT0wwAAAFtgwQTKAAABAMARjBEAiBb/gW1RU7kgFBiNpHx\n" +
+            "LStujKIocyENUTXsMbsac+LktwIgXbEr8vOOCEdBdXQ2F/FKec8ft6gz57mHNmwl\n" +
+            "pp7phbQAdgC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DBBM6\n" +
+            "AAAEAwBHMEUCIQDjKN3h86ofR94+JxLFoYuoA+DRtxEY8XGg+NQXlZfUrgIgEoO2\n" +
+            "ZzKbGfohdwj/WtDwJDRX5pjXF4M0nECiwtYXDIwwCgYIKoZIzj0EAwIDSAAwRQIg\n" +
+            "AkIRVQBwrElFjrnqk5XPvnlnwkIm1A70ayqOf1FexoQCIQC8tBTn//RCfrhcgTjd\n" +
+            "ER4wRjFfFoc6lC68OHGVg9CZZg==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
     // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
     // ST=Greater Manchester, C=GB
     // Serial number: 603a5c2f85b63e00ba46ce8c3f6000b0
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIGXzCCBgWgAwIBAgIQYDpcL4W2PgC6Rs6MP2AAsDAKBggqhkjOPQQDAjCBkjEL\n" +
             "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" +
             "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" +
@@ -307,52 +351,6 @@
             "KOC7\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
-    // ST=Greater Manchester, C=GB
-    // Serial number: 414e5d66ec7d15ca504213f2811d57af
-    // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIGYDCCBgWgAwIBAgIQQU5dZux9FcpQQhPygR1XrzAKBggqhkjOPQQDAjCBkjEL\n" +
-            "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" +
-            "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" +
-            "L0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" +
-            "MB4XDTE3MDcwNDAwMDAwMFoXDTE5MTAwMzIzNTk1OVowggFZMREwDwYDVQQFEwgw\n" +
-            "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" +
-            "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExGzAZBgNV\n" +
-            "BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEWMBQGA1UE\n" +
-            "CRMNVHJhZmZvcmQgUm9hZDEWMBQGA1UECRMNRXhjaGFuZ2UgUXVheTElMCMGA1UE\n" +
-            "CRMcM3JkIEZsb29yLCAyNiBPZmZpY2UgVmlsbGFnZTEaMBgGA1UEChMRQ09NT0RP\n" +
-            "IENBIExpbWl0ZWQxFjAUBgNVBAsTDUNPTU9ETyBFViBTU0wxODA2BgNVBAMTL2Nv\n" +
-            "bW9kb2VjY2NlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMFkw\n" +
-            "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt26qBS7TRu/yfR+RiqLAzW2C+UspFZlO\n" +
-            "Rc4EhLfNYMgFkoZKjEnwJzudH6a+uRPqPOhPgUd6PFfRQFOcLjmhgaOCA3EwggNt\n" +
-            "MB8GA1UdIwQYMBaAFNNOwxm6WFnRHGC3YVNHO6d3j/iKMB0GA1UdDgQWBBTpZ0tz\n" +
-            "KscFw6Z3vCEDFzGR5VSkVzAOBgNVHQ8BAf8EBAMCBYAwDAYDVR0TAQH/BAIwADAd\n" +
-            "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA7BgwrBgEE\n" +
-            "AbIxAQIBBQEwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNv\n" +
-            "bS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21v\n" +
-            "ZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVy\n" +
-            "Q0EuY3JsMIGHBggrBgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQu\n" +
-            "Y29tb2RvY2EuY29tL0NPTU9ET0VDQ0V4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNl\n" +
-            "cnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29t\n" +
-            "MDoGA1UdEQQzMDGCL2NvbW9kb2VjY2NlcnRpZmljYXRpb25hdXRob3JpdHktZXYu\n" +
-            "Y29tb2RvY2EuY29tMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgCkuQmQtBhY\n" +
-            "FIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAV0NLqsqAAAEAwBHMEUCIAz9Jjq3\n" +
-            "qLUd/a2PYZnLGsEG/MrL7vab5rmGBg8RGAJxAiEA7JJnar07NIjCLLO77xJ3UFcu\n" +
-            "UMM3M8JgGC8wbuRwxbUAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ\n" +
-            "3QAAAV0NLqjmAAAEAwBHMEUCIHRvPWKr7vPMBWx1gLPkt8inPINWPNSoax178e5A\n" +
-            "D0cPAiEAvRL/VP4DLiyHvcU9AOqTzQXGuWCzswWKG59hSm7gS4kAdQDuS723dc5g\n" +
-            "uuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAV0NLqsDAAAEAwBGMEQCIFALT043\n" +
-            "X5IffLsxIAGXTrWgkZHf12QKgrYKXVB629eOAiAIeci2xi3fUW6mU8tT4LwyjowV\n" +
-            "DkrSCw1ZMo0JApsfzTAKBggqhkjOPQQDAgNJADBGAiEA7HUxjwx0MBC+4PuPx4Z1\n" +
-            "WpKz7jdHOMTh1sdaoVV5hNoCIQDrnjBFUopXHTvm/rj+aMFIeYejggPqv14KJOqT\n" +
-            "gym+uA==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
         pathValidator.validate(new String[]{VALID, INT},
@@ -361,19 +359,61 @@
         // Validate Revoked
         pathValidator.validate(new String[]{REVOKED, INT},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 08:12:02 PST 2018", System.out);
+                "Wed Oct 02 06:05:57 PDT 2019", System.out);
     }
 }
 
 class ComodoUserTrustRSA {
 
+    // Owner: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Issuer: CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US
+    // Serial number: 284e39c14b386d889c7299e58cd05a57
+    // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030
+    private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGNDCCBBygAwIBAgIQKE45wUs4bYiccpnljNBaVzANBgkqhkiG9w0BAQwFADCB\n" +
+            "iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n" +
+            "cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n" +
+            "BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx\n" +
+            "MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBkTELMAkGA1UEBhMCR0IxGzAZBgNV\n" +
+            "BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE\n" +
+            "ChMPU2VjdGlnbyBMaW1pdGVkMTkwNwYDVQQDEzBTZWN0aWdvIFJTQSBFeHRlbmRl\n" +
+            "ZCBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUA\n" +
+            "A4IBDwAwggEKAoIBAQCaoslYBiqFev0Yc4TXPa0s9oliMcn9VaENfTUK4GVT7niB\n" +
+            "QXxC6Mt8kTtvyr5lU92hDQDh2WDPQsZ7oibh75t2kowT3z1S+Sy1GsUDM4NbdOde\n" +
+            "orcmzFm/b4bwD4G/G+pB4EX1HSfjN9eT0Hje+AGvCrd2MmnxJ+Yymv9BH9OB65jK\n" +
+            "rUO9Na4iHr48XWBDFvzsPCJ11Uioof6dRBVp+Lauj88Z7k2X8d606HeXn43h6acp\n" +
+            "LLURWyqXM0CrzedVWBzuXKuBEaqD6w/1VpLJvSU+wl3ScvXSLFp82DSRJVJONXWl\n" +
+            "dp9gjJioPGRByeZw11k3galbbF5gFK9xSnbDx29LAgMBAAGjggGNMIIBiTAfBgNV\n" +
+            "HSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQULGn/gMmHkK40\n" +
+            "4bTnTJOFmUDpp7IwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\n" +
+            "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDoGA1UdIAQzMDEwLwYEVR0g\n" +
+            "ADAnMCUGCCsGAQUFBwIBFhlodHRwczovL2Nwcy51c2VydHJ1c3QuY29tMFAGA1Ud\n" +
+            "HwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RS\n" +
+            "U0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYI\n" +
+            "KwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FB\n" +
+            "ZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0\n" +
+            "LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAQ4AzPxVypLyy3IjUUmVl7FaxrHsXQq2z\n" +
+            "Zt2gKnHQShuA+5xpRPNndjvhHk4D08PZXUe6Im7E5knqxtyl5aYdldb+HI/7f+zd\n" +
+            "W/1ub2N4Vq4ZYUjcZ1ECOFK7Z2zoNicDmU+Fe/TreXPuPsDicTG/tMcWEVM558OQ\n" +
+            "TJkB2LK3ZhGukWM/RTMRcRdXaXOX8Lh0ylzRO1O0ObXytvOFpkkkD92HGsfS06i7\n" +
+            "NLDPJEeZXqzHE5Tqj7VSAj+2luwfaXaPLD8lQEVci8xmsPGOn0mXE1ZzsChEPhVq\n" +
+            "FYQUsbiRJRhidKauhd+G2CkRTcR5fpsuz+iStB9s5Fks9lKoXnn0hv78VYjvR78C\n" +
+            "Cvj5FW/ounHjWTWMb3il9S5ngbFGcelB1l/MQkR63+1ybdi2OpjNWJCftxOWUpkC\n" +
+            "xaRdnOnSj7GQY0NLn8Gtq9FcSZydtkVgXpouSFZkXNS/MYwbcCCcRKBbrk8ss0SI\n" +
+            "Xg1gTURjh9VP1OHm0OktYcUw9e90wHIDn7h0qA+bWOsZquSRzT4s2crF3ZSA3tuV\n" +
+            "/UJ33mjdVO8wBD8aI5y10QreSPJvZHHNDyCmoyjXvNhR+u3arXUoHWxO+MZBeXbi\n" +
+            "iF7Nwn/IEmQvWBW8l6D26CXIavcY1kAJcfyzHkrPbLo+fAOa/KFl3lIU+0biEVNk\n" +
+            "Q9zXE6hC6X4=\n" +
+            "-----END CERTIFICATE-----";
+
     // Owner: CN=USERTrust RSA Extended Validation Secure Server CA,
     // O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US
     // Issuer: CN=USERTrust RSA Certification Authority, O=The USERTRUST Network,
     // L=Jersey City, ST=New Jersey, C=US
     // Serial number: f6bb751efa7d2e8368e606407334f83
     // Valid from: Sat Feb 11 16:00:00 PST 2012 until: Thu Feb 11 15:59:59 PST 2027
-    private static final String INT = "-----BEGIN CERTIFICATE-----\n"
+    private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n"
             + "MIIGGTCCBAGgAwIBAgIQD2u3Ue+n0ug2jmBkBzNPgzANBgkqhkiG9w0BAQwFADCB\n"
             + "iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n"
             + "cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n"
@@ -409,15 +449,69 @@
             + "4fokbdNREXoShKClNIPbB5iY+WdSzb9CKLyb96g=\n"
             + "-----END CERTIFICATE-----";
 
-    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL,
-    // O=Sectigo Limited, STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road,
-    // L=Salford, ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
+    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, ST=Manchester,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: b07fd164b5790c9d5d1fddff5819cdb2
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIH5TCCBs2gAwIBAgIRALB/0WS1eQydXR/d/1gZzbIwDQYJKoZIhvcNAQELBQAw\n" +
+            "gZExCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" +
+            "BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UE\n" +
+            "AxMwU2VjdGlnbyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy\n" +
+            "IENBMB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFWMREwDwYDVQQF\n" +
+            "EwgwNDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0\n" +
+            "ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEzAR\n" +
+            "BgNVBAgTCk1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRy\n" +
+            "YWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNy\n" +
+            "ZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGDAWBgNVBAoTD1NlY3RpZ28gTGlt\n" +
+            "aXRlZDEaMBgGA1UECxMRQ09NT0RPIEVWIFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0\n" +
+            "cnVzdHJzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMIIB\n" +
+            "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnh/rxeiYwpLa651eLvGnR+RE\n" +
+            "rhDWkTZtqZcHw9Oy7JL2uELyEPbM+v0az40cBHS0bQZJZbWmXNukMUMSwIb4z7t8\n" +
+            "OXlxz9uvxEufvlqBl4qeC/z3LpFBRRHEero3yGKVwkoe1aP2Pq7Udi+7i7eVZZdA\n" +
+            "1ticxZWo/UBU9mwbIOYqf/4xzZ6G891hKb+NAuuEfxG52vXZl8odMThfHuDlkfS7\n" +
+            "nZMQBaO40KJeSEBhr+5TIS7d7tWWye/F6oEQ0+dHBiF9PyZ1dXoO8aue/80mP+0F\n" +
+            "MYTmRFsKHge6ZjojfH9cLlR5kTqtP5Tqh5GBQ4zp3uyIBBU6ylKp9PNHkewGUQID\n" +
+            "AQABo4IDbjCCA2owHwYDVR0jBBgwFoAULGn/gMmHkK404bTnTJOFmUDpp7IwHQYD\n" +
+            "VR0OBBYEFHz7cvDn1LYe2M+z4plwQn7rt938MA4GA1UdDwEB/wQEAwIFoDAMBgNV\n" +
+            "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNVHSAE\n" +
+            "QjBAMDUGDCsGAQQBsjEBAgEFATAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp\n" +
+            "Z28uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3Js\n" +
+            "LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FFeHRlbmRlZFZhbGlkYXRpb25TZWN1cmVT\n" +
+            "ZXJ2ZXJDQS5jcmwwgYYGCCsGAQUFBwEBBHoweDBRBggrBgEFBQcwAoZFaHR0cDov\n" +
+            "L2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2Vj\n" +
+            "dXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" +
+            "LmNvbTA9BgNVHREENjA0gjJ1c2VydHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9y\n" +
+            "aXR5LWV2LmNvbW9kb2NhLmNvbTCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA\n" +
+            "7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFtgzv54wAABAMARzBF\n" +
+            "AiB5PmhsK3zU3XdKvyxw/wWHMmLI7apHLa1yKdjkA8H+ggIhALdUx7Tl8aeWhK6z\n" +
+            "lh+PHvMAdCcAJK6w9qBJGQtSrYO5AHUAVYHUwhaQNgFK6gubVzxT8MDkOHhwJQgX\n" +
+            "L6OqHQcT0wwAAAFtgzv5zgAABAMARjBEAiBumSwAUamibqJXTN2cf/H3mjd0T35/\n" +
+            "UK9w2hu9gFobxgIgSXTLndHyqFUmcmquu3It0WC1yl6YMceGixbQL1e8BQcAdwC7\n" +
+            "2d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DO/nXAAAEAwBIMEYC\n" +
+            "IQDHRs10oYoXE5yq6WsiksjdQsUWZNpbSsrmz0u+KlxTVQIhAJ4rvHItKSeJLkaN\n" +
+            "S3YpVZnkN8tOwuxPsYeyVx/BtaNpMA0GCSqGSIb3DQEBCwUAA4IBAQAPFIsUFymo\n" +
+            "VTp0vntHrZpBApBQzDeriQv7Bi7tmou/Ng47RtXW3DjGdrePGSfOdl7h62k8qprU\n" +
+            "JeLyloDqhvmT/CG/hdwrfZ3Sv3N2xpetGcnW5S3oEi3m+/M1ls9eD+x1vybqV9Kd\n" +
+            "lcjuV7SYDlbvAS9w7TcygudhdW0cI8XTCvesGKohBkAlqaQ/MWYpt4WvsxHjbWgn\n" +
+            "5ZlIYR6A1ZFEjADifViH/5AA79lgGhAskkIWPjvRFalEVKTKtjhRK76eCfZs4Frr\n" +
+            "CEOpon+BeNKk+x/K/r10dSoWe0SV2uGVxTD83zkP++eREwo1hTgn8bXn7ftlnA3j\n" +
+            "7ml+Usz6udaD\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=USERTrust RSA Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
     // ST=New Jersey, C=US
     // Serial number: d3c204e8df6a1539568cf15e97e57b1d
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIIADCCBuigAwIBAgIRANPCBOjfahU5VozxXpflex0wDQYJKoZIhvcNAQELBQAw\n" +
             "gZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK\n" +
             "ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYD\n" +
@@ -463,81 +557,56 @@
             "3Ld31zbQaywKdpCsT74/hEBMfcDiP02mmtyrlqHD4R3tdYne\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=USERTrust RSA Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
-    // ST=New Jersey, C=US
-    // Serial number: ffcada019c9fb1155a32300083cb99c9
-    // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIIATCCBumgAwIBAgIRAP/K2gGcn7EVWjIwAIPLmckwDQYJKoZIhvcNAQELBQAw\n" +
-            "gZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK\n" +
-            "ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYD\n" +
-            "VQQDEzJVU0VSVHJ1c3QgUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNl\n" +
-            "cnZlciBDQTAeFw0xNzA3MDQwMDAwMDBaFw0xOTEwMDMyMzU5NTlaMIIBYDERMA8G\n" +
-            "A1UEBRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFBy\n" +
-            "aXZhdGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VR\n" +
-            "MRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQx\n" +
-            "FjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkx\n" +
-            "JTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGjAYBgNVBAoT\n" +
-            "EUNPTU9ETyBDQSBMaW1pdGVkMRowGAYDVQQLExFDT01PRE8gRVYgU0dDIFNTTDE7\n" +
-            "MDkGA1UEAxMydXNlcnRydXN0cnNhY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5j\n" +
-            "b21vZG9jYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCeH+vF\n" +
-            "6JjCktrrnV4u8adH5ESuENaRNm2plwfD07Lskva4QvIQ9sz6/RrPjRwEdLRtBkll\n" +
-            "taZc26QxQxLAhvjPu3w5eXHP26/ES5++WoGXip4L/PcukUFFEcR6ujfIYpXCSh7V\n" +
-            "o/Y+rtR2L7uLt5Vll0DW2JzFlaj9QFT2bBsg5ip//jHNnobz3WEpv40C64R/Ebna\n" +
-            "9dmXyh0xOF8e4OWR9LudkxAFo7jQol5IQGGv7lMhLt3u1ZbJ78XqgRDT50cGIX0/\n" +
-            "JnV1eg7xq57/zSY/7QUxhOZEWwoeB7pmOiN8f1wuVHmROq0/lOqHkYFDjOne7IgE\n" +
-            "FTrKUqn080eR7AZRAgMBAAGjggN8MIIDeDAfBgNVHSMEGDAWgBQvgU/iZvq8aL+Z\n" +
-            "Q4RSiSA6gvOkpTAdBgNVHQ4EFgQUfPty8OfUth7Yz7PimXBCfuu33fwwDgYDVR0P\n" +
-            "AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\n" +
-            "AQUFBwMCMEsGA1UdIAREMEIwNwYMKwYBBAGyMQECAQUBMCcwJQYIKwYBBQUHAgEW\n" +
-            "GWh0dHBzOi8vY3BzLnVzZXJ0cnVzdC5jb20wBwYFZ4EMAQEwWgYDVR0fBFMwUTBP\n" +
-            "oE2gS4ZJaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdFJTQUV4dGVu\n" +
-            "ZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNybDCBjQYIKwYBBQUHAQEEgYAw\n" +
-            "fjBVBggrBgEFBQcwAoZJaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVz\n" +
-            "dFJTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAlBggrBgEF\n" +
-            "BQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTA9BgNVHREENjA0gjJ1c2Vy\n" +
-            "dHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCC\n" +
-            "AX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5\n" +
-            "G9+443fNDsgN3BAAAAFdDU2iYQAABAMARzBFAiB0o4GnVHD8MeVQ32D0XYu+EQQW\n" +
-            "jvN78rmCfk0OEBxyFAIhAKgyctIn0IaDJiZzsrtAiqEnkcMtuh8o+R0Rqw1ygAjk\n" +
-            "AHcAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFdDU2gFgAABAMA\n" +
-            "SDBGAiEA7mcmZ8H5uHuNCdI0CVxsqDZQcZX/gVk94KckePkzQoACIQCHwm5hcvNC\n" +
-            "M8vNmFkboQN79DglRctHrlh143A6mUTk8QB2AO5Lvbd1zmC64UJpH6vhnmajD35f\n" +
-            "sHLYgwDEe4l6qP3LAAABXQ1NojoAAAQDAEcwRQIhAPqwijgE0Fr6uJ+yF+TvyXco\n" +
-            "Hduv9h7R5WWwJfghXiMyAiBB4+fJm4rIcOnJBZmOqFnRpIjPN0jwDqJT0nDHxaXA\n" +
-            "nDANBgkqhkiG9w0BAQsFAAOCAQEACXitF1bTEvV1HX11WrT/XuoMhsoPK4TS16rs\n" +
-            "FqztV4iXKlA1/h5qbsjYY1gVrM+/6kQkmEs5qrxsek2WNxY80NO3WAzroRJ3H9Sd\n" +
-            "mPn0No2P8LZ5Fs5hvaD/PfWO5xxey80c3kGyvWOej90P3IrL/1RiULyh95TrXBjI\n" +
-            "ddCBsZ28904wsQUrPBPMpiu0DKl1HR/em9WkcipMi+onJxxFWjucssz5PW/BzGYF\n" +
-            "jfWLDEI0tN5L4CWV3iVXFXOURY1Mwhtsey9jvlEyxSsys55QdKF40yGgtV9VC+os\n" +
-            "7hJP33+qA0cvCTaRytiPP6z/l2G/KSIXTyv6SxzGhsTFfzLAOg==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
-        pathValidator.validate(new String[]{VALID, INT},
+        pathValidator.validate(new String[]{VALID, INT_VALID},
                 ValidatePathWithParams.Status.GOOD, null, System.out);
 
         // Validate Revoked
-        pathValidator.validate(new String[]{REVOKED, INT},
+        pathValidator.validate(new String[]{REVOKED, INT_REVOKED},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 10:58:13 PST 2018", System.out);
+                "Wed Oct 02 06:07:12 PDT 2019", System.out);
     }
 }
 
 class ComodoUserTrustECC {
 
+    // Owner: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Issuer: CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US
+    // Serial number: 80f5606d3a162b143adc12fbe8c2066f
+    // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030
+    private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIDyTCCA0+gAwIBAgIRAID1YG06FisUOtwS++jCBm8wCgYIKoZIzj0EAwMwgYgx\n" +
+            "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" +
+            "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQD\n" +
+            "EyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEw\n" +
+            "MjAwMDAwMFoXDTMwMTIzMTIzNTk1OVowgZExCzAJBgNVBAYTAkdCMRswGQYDVQQI\n" +
+            "ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT\n" +
+            "D1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMwU2VjdGlnbyBFQ0MgRXh0ZW5kZWQg\n" +
+            "VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" +
+            "AQcDQgAEAyJ5Ca9JyXq8bO+krLVWysbtm7fdMSJ54uFD23t0x6JAC4IjxevfQJzW\n" +
+            "z4T6yY+FybTBqtOa++ijJFnkB5wKy6OCAY0wggGJMB8GA1UdIwQYMBaAFDrhCYbU\n" +
+            "zxnClnZ0SXbc4DXGY2OaMB0GA1UdDgQWBBTvwSqVDDLa+3Mw3IoT2BVL9xPo+DAO\n" +
+            "BgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggr\n" +
+            "BgEFBQcDAQYIKwYBBQUHAwIwOgYDVR0gBDMwMTAvBgRVHSAAMCcwJQYIKwYBBQUH\n" +
+            "AgEWGWh0dHBzOi8vY3BzLnVzZXJ0cnVzdC5jb20wUAYDVR0fBEkwRzBFoEOgQYY/\n" +
+            "aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0NlcnRpZmljYXRp\n" +
+            "b25BdXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0\n" +
+            "cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0FkZFRydXN0Q0EuY3J0\n" +
+            "MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMAoGCCqGSM49\n" +
+            "BAMDA2gAMGUCMQCjHztBDL90GCRXHlGqm0H7kzP04hd0MxwakKjWzOmstXNFLONj\n" +
+            "RFa0JqI/iKUJMFcCMCbLgyzcFW7DihtY5XE0XCLCw+git0NjxiFB6FaOFIlyDdqT\n" +
+            "j+Th+DJ92JLvICVD/g==\n" +
+            "-----END CERTIFICATE-----";
+
     // Owner: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network,
     // L=Jersey City, ST=New Jersey, C=US
     // Issuer: CN=USERTrust ECC Certification Authority, O=The USERTRUST Network,
     // L=Jersey City, ST=New Jersey, C=US
     // Serial number: 3d09b24f5c08a7ce8eb85a51d3c1aa52
     // Valid from: Sun Apr 14 17:00:00 PDT 2013 until: Fri Apr 14 16:59:59 PDT 2028
-    private static final String INT = "-----BEGIN CERTIFICATE-----\n"
+    private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n"
             + "MIIDwTCCA0igAwIBAgIQPQmyT1wIp86OuFpR08GqUjAKBggqhkjOPQQDAzCBiDEL\n"
             + "MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl\n"
             + "eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT\n"
@@ -563,13 +632,58 @@
 
     // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
     // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: 8b72489b7f505a55e2a22659c90ed2ab
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGRTCCBeugAwIBAgIRAItySJt/UFpV4qImWckO0qswCgYIKoZIzj0EAwIwgZEx\n" +
+            "CzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNV\n" +
+            "BAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMw\n" +
+            "U2VjdGlnbyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" +
+            "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFBMREwDwYDVQQFEwgw\n" +
+            "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" +
+            "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" +
+            "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" +
+            "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" +
+            "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEaMBgGA1UECxMRQ09NT0RPIEVW\n" +
+            "IFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0cnVzdGVjY2NlcnRpZmljYXRpb25hdXRo\n" +
+            "b3JpdHktZXYuY29tb2RvY2EuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\n" +
+            "LTJfEd92Wlg+h/AVtPsMmwX9Puvi+WGCv3sgFRpur8Iy2kGVpXHRQTCn2j9aky4t\n" +
+            "FQGm7OG2klJA/MEeevKVaaOCA28wggNrMB8GA1UdIwQYMBaAFO/BKpUMMtr7czDc\n" +
+            "ihPYFUv3E+j4MB0GA1UdDgQWBBSzrWHzmiHwx2Rrm7SjRC0UegNrKzAOBgNVHQ8B\n" +
+            "Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" +
+            "BQUHAwIwSQYDVR0gBEIwQDA1BgwrBgEEAbIxAQIBBQEwJTAjBggrBgEFBQcCARYX\n" +
+            "aHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmg\n" +
+            "R4ZFaHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvRUNDRXh0ZW5kZWRWYWxp\n" +
+            "ZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGGBggrBgEFBQcBAQR6MHgwUQYIKwYB\n" +
+            "BQUHMAKGRWh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb0VDQ0V4dGVuZGVk\n" +
+            "VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYXaHR0cDov\n" +
+            "L29jc3Auc2VjdGlnby5jb20wPQYDVR0RBDYwNIIydXNlcnRydXN0ZWNjY2VydGlm\n" +
+            "aWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF/BgorBgEEAdZ5AgQC\n" +
+            "BIIBbwSCAWsBaQB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAAB\n" +
+            "bYL/SJoAAAQDAEcwRQIhAL7EJt/Rgz6NBnx2v8Hevux3Gpcxy64kaeyLVgFeNqFk\n" +
+            "AiBRf+OWLOtZzEav/oERljrk8hgZB4CR1nj/Tn98cmRrwwB2AFWB1MIWkDYBSuoL\n" +
+            "m1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYL/SIgAAAQDAEcwRQIgVtZZaiBMC2lu\n" +
+            "atBzUHQmOq4qrUQP7nS83cd3VzPhToECIQDnlpOCdaxJwr8C0MtkvYpKSabwBPFL\n" +
+            "ASEkwmOpjuQErAB3ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAAB\n" +
+            "bYL/SJoAAAQDAEgwRgIhAI8OgzP/kzF1bOJRHU2S/ewij/6HpGPy7Mbm7Hyuv3IU\n" +
+            "AiEAxDmX2FmORlgeerQmQ+ar3D9/TwA9RQckVDu5IrgweREwCgYIKoZIzj0EAwID\n" +
+            "SAAwRQIhAPwQWGWd3oR7YJ7ngCDQ9TAbdPgND51SiR34WfEgaTQtAiAxD4umKm02\n" +
+            "59GEMj5NpyF2ZQEq5mEGcjJNojrn+PC4zg==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
     // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
     // ST=New Jersey, C=US
     // Serial number: ab1455f9833ae7783f95de8744181f6a
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIGhjCCBiygAwIBAgIRAKsUVfmDOud4P5Xeh0QYH2owCgYIKoZIzj0EAwIwgZUx\n" +
             "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" +
             "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYDVQQD\n" +
@@ -607,60 +721,14 @@
             "11EPtBSCEhUCIBcyI0yl5dRff6+4x8IeCrLiAOYsfzM7Y/a5uRKFnbYz\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
-    // ST=New Jersey, C=US
-    // Serial number: 9bd0c93cac9ca2edc1a7dd923316b3c6
-    // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIGhzCCBi2gAwIBAgIRAJvQyTysnKLtwafdkjMWs8YwCgYIKoZIzj0EAwIwgZUx\n" +
-            "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" +
-            "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYDVQQD\n" +
-            "EzJVU0VSVHJ1c3QgRUNDIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" +
-            "ciBDQTAeFw0xNzA3MDQwMDAwMDBaFw0xOTEwMDMyMzU5NTlaMIIBYDERMA8GA1UE\n" +
-            "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" +
-            "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRsw\n" +
-            "GQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAU\n" +
-            "BgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAj\n" +
-            "BgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGjAYBgNVBAoTEUNP\n" +
-            "TU9ETyBDQSBMaW1pdGVkMRowGAYDVQQLExFDT01PRE8gRVYgU0dDIFNTTDE7MDkG\n" +
-            "A1UEAxMydXNlcnRydXN0ZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21v\n" +
-            "ZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQtMl8R33ZaWD6H8BW0\n" +
-            "+wybBf0+6+L5YYK/eyAVGm6vwjLaQZWlcdFBMKfaP1qTLi0VAabs4baSUkD8wR56\n" +
-            "8pVpo4IDjjCCA4owHwYDVR0jBBgwFoAUKpxa+U6hMNpASyvpS/H1nNwC+S4wHQYD\n" +
-            "VR0OBBYEFLOtYfOaIfDHZGubtKNELRR6A2srMA4GA1UdDwEB/wQEAwIFgDAMBgNV\n" +
-            "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBQBgNVHSAE\n" +
-            "STBHMDwGDCsGAQQBsjEBAgEFATAsMCoGCCsGAQUFBwIBFh5odHRwczovL2Nwcy50\n" +
-            "cnVzdC1wcm92aWRlci5jb20wBwYFZ4EMAQEwXwYDVR0fBFgwVjBUoFKgUIZOaHR0\n" +
-            "cDovL2NybC50cnVzdC1wcm92aWRlci5jb20vVVNFUlRydXN0RUNDRXh0ZW5kZWRW\n" +
-            "YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGYBggrBgEFBQcBAQSBizCBiDBa\n" +
-            "BggrBgEFBQcwAoZOaHR0cDovL2NydC50cnVzdC1wcm92aWRlci5jb20vVVNFUlRy\n" +
-            "dXN0RUNDRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCoGCCsG\n" +
-            "AQUFBzABhh5odHRwOi8vb2NzcC50cnVzdC1wcm92aWRlci5jb20wPQYDVR0RBDYw\n" +
-            "NIIydXNlcnRydXN0ZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9j\n" +
-            "YS5jb20wggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB1AKS5CZC0GFgUh7sTosxn\n" +
-            "cAo8NZgE+RvfuON3zQ7IDdwQAAABXQ0/jQ0AAAQDAEYwRAIgPbaNWgoi6OfyNwL2\n" +
-            "+jiySsoLrkx+0d4NJE1WnZQcfzwCICW4yvsXaMxoOXpQp3EPgrYk5Ajfvy/dY3Ui\n" +
-            "0/dbQtHxAHYAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFdDT+K\n" +
-            "xwAABAMARzBFAiB3GQasrX+akoHX02ZvXCcvhWCqv6qQOhLCUqflPoRbuAIhALwe\n" +
-            "hrQo8S1Tm5vbMcxGiViq5ZcawxENWhxZ9hS0BZweAHUA7ku9t3XOYLrhQmkfq+Ge\n" +
-            "ZqMPfl+wctiDAMR7iXqo/csAAAFdDT+M4AAABAMARjBEAiAjvp8w/fdTVW1VGE0T\n" +
-            "I0YcCIXTYFDgzUMsEUiKHANAgwIgETQUcac7Hiis2fgQ+GdGF9yuh+xMo2Z8QXNu\n" +
-            "1Cknf+8wCgYIKoZIzj0EAwIDSAAwRQIgQ5UiUI7xodmmMYNs3CmqlZHw/04BQRAR\n" +
-            "4gRm7blZSIMCIQDHvIWTaPzSO6vwVzs6wSD6FqebLiFxoddC6aZG8Nm0wQ==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
-        pathValidator.validate(new String[]{VALID, INT},
+        pathValidator.validate(new String[]{VALID, INT_VALID},
                 ValidatePathWithParams.Status.GOOD, null, System.out);
 
         // Validate Revoked
-        pathValidator.validate(new String[]{REVOKED, INT},
+        pathValidator.validate(new String[]{REVOKED, INT_REVOKED},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 10:06:00 PST 2018", System.out);
+                "Wed Oct 02 06:06:50 PDT 2019", System.out);
     }
 }
diff --git a/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java b/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java
new file mode 100644
index 0000000..63ba5e1
--- /dev/null
+++ b/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2019, 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 8232019
+ * @summary Interoperability tests with LuxTrust Global Root 2 CA
+ * @build ValidatePathWithParams
+ * @run main/othervm -Djava.security.debug=certpath LuxTrustCA OCSP
+ * @run main/othervm -Djava.security.debug=certpath LuxTrustCA CRL
+ */
+
+/*
+ * Obtain TLS test artifacts for LuxTrust CAs from:
+ *
+ * LuxTrust Global Root 2 CA sent test certificates as attachment
+ */
+public class LuxTrustCA {
+
+    // Owner: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+    // Issuer: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
+    // Serial number: 413dea1a28c2253845558e047f3e2a8b5b9baeae
+    // Valid from: Fri Mar 06 06:12:15 PST 2015 until: Mon Mar 05 05:21:57 PST 2035
+    private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGcjCCBFqgAwIBAgIUQT3qGijCJThFVY4Efz4qi1ubrq4wDQYJKoZIhvcNAQEL\n" +
+            "BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV\n" +
+            "BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA2MTQxMjE1WhcNMzUw\n" +
+            "MzA1MTMyMTU3WjBOMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B\n" +
+            "LjEnMCUGA1UEAwweTHV4VHJ1c3QgR2xvYmFsIFF1YWxpZmllZCBDQSAzMIICIjAN\n" +
+            "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuZ5iXSmFbP80gWb0kieYsImcyIo3\n" +
+            "QYg+XA3NlwH6QtI0PgZEG9dSo8pM7VMIzE5zq8tgJ50HnPdYflvfhkEKvAW2NuNX\n" +
+            "6hi/6HK4Nye+kB+INjpfAHmLft3GT95e+frk/t7hJNorK44xzqfWZKLNGysEHIri\n" +
+            "ddcePWOk3J/VMc9CsSemeZbmeZW1/xXeqolMS7JIDZ3+0DgVCYsKIK+b3sAQ8iqX\n" +
+            "bQlQyvymG6QyoQoJbuEP23iawRMWKNWk+sjzOkPAAQDtgEEVdggzzudLSM04C5Cj\n" +
+            "eLlLYuXgljler9bKRk9wW8nkareLZsn9uCDihGXGyC5m9jseGY1KAnlV8usLjBFA\n" +
+            "iW5OCnzcOg+CPsVucoRhS6uvXcu7VtHRGo5yLysJVv7sj6cx5lMvQKAMLviVi3kp\n" +
+            "hZKYfqVLAVFJpXTpunY2GayVGf/uOpzNoiSRpcxxYjmAlPKNeTgXVl5Mc0zojgT/\n" +
+            "MZTGFN7ov7n01yodN6OhfTADacvaKfj2C2CwdCJvMqvlUuCKrvuXbdZrtRm3BZXr\n" +
+            "ghGhuQmG0Tir7VVCI0WZjVjyHs2rpUcCQ6+D1WymKhzp0mrXdaFzYRce7FrEk69J\n" +
+            "WzWVp/9/GKnnb0//camavEaI4V64MVxYAir5AL/j7d4JIOqhPPU14ajxmC6dEH84\n" +
+            "guVs0Lo/dwVTUzsCAwEAAaOCAU4wggFKMBIGA1UdEwEB/wQIMAYBAf8CAQAwQwYD\n" +
+            "VR0gBDwwOjA4BggrgSsBAQEKAzAsMCoGCCsGAQUFBwIBFh5odHRwczovL3JlcG9z\n" +
+            "aXRvcnkubHV4dHJ1c3QubHUwagYIKwYBBQUHAQEEXjBcMCsGCCsGAQUFBzABhh9o\n" +
+            "dHRwOi8vbHRncm9vdC5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFodHRw\n" +
+            "Oi8vY2EubHV4dHJ1c3QubHUvTFRHUkNBMi5jcnQwDgYDVR0PAQH/BAQDAgEGMB8G\n" +
+            "A1UdIwQYMBaAFP8YKHb5SAUsoa7xKxsrslP4S3yzMDMGA1UdHwQsMCowKKAmoCSG\n" +
+            "Imh0dHA6Ly9jcmwubHV4dHJ1c3QubHUvTFRHUkNBMi5jcmwwHQYDVR0OBBYEFGOP\n" +
+            "wosDsauO2FNHlh2ZqH32rKh1MA0GCSqGSIb3DQEBCwUAA4ICAQADB6M/edbOO9iJ\n" +
+            "COnVxayJ1NBk08/BVKlHwe7HBYAzT6Kmo3TbMUwOpcGI2e/NBCR3F4wTzXOVvFmv\n" +
+            "dBl7sdS6uMSLBTrav+5LChcFDBQj26X5VQDcXkA8b/u6J4Ve7CwoSesYg9H0fsJ3\n" +
+            "v12QrmGUUao9gbamKP1TFriO+XiIaDLYectruusRktIke9qy8MCpNSarZqr3oD3c\n" +
+            "/+N5D3lDlGpaz1IL8TpbubFEQHPCr6JiwR+qSqGRfxv8vIvOOAVxe7np5QhtwmCk\n" +
+            "XdMOPQ/XOOuEA06bez+zHkASX64at7dXru+4JUEbpijjMA+1jbFZr20OeBIQZL7o\n" +
+            "Est+FF8lFuvmucC9TS9QnlF28WJExvpIknjS7LhFMGXB9w380q38ZOuKjPZpoztY\n" +
+            "eyUpf8gxzV7fE5Q1okhnsDZ+12vBzBruzJcwtNuXyLyIh3fVN0LunVd+NP2kGjB2\n" +
+            "t9WD2Y0CaKxWx8snDdrSbAi46TpNoe04eroWgZOvdN0hEmf2d8tYBSJ/XZekU9sC\n" +
+            "Aww5vxHnXJi6CZHhjt8f1mMhyE2gBvmpk4CFetViO2sG0n/nsxCQNpnclsax/eJu\n" +
+            "XmGiZ3OPCIRijI5gy3pLRgnbgLyktWoOkmT/gxtWDLfVZwEt52JL8d550KIgttyR\n" +
+            "qX81LJWGSDdpnzeRVQEnzAt6+RebAQ==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: T=Private Person, SERIALNUMBER=00100978855105608536,
+    // GIVENNAME=TokenPRIActive, SURNAME=Test, CN=TokenPRIActive Test, C=DE
+    // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+    // Serial number: 3814b6
+    // Valid from: Wed Jul 10 04:36:12 PDT 2019 until: Sun Jul 10 04:36:12 PDT 2022
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIG/jCCBOagAwIBAgIDOBS2MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" +
+            "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" +
+            "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjEyWhcNMjIwNzEwMTEzNjEy\n" +
+            "WjCBizELMAkGA1UEBhMCREUxHDAaBgNVBAMTE1Rva2VuUFJJQWN0aXZlIFRlc3Qx\n" +
+            "DTALBgNVBAQTBFRlc3QxFzAVBgNVBCoTDlRva2VuUFJJQWN0aXZlMR0wGwYDVQQF\n" +
+            "ExQwMDEwMDk3ODg1NTEwNTYwODUzNjEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24w\n" +
+            "ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDb8l2RJNS7iA9hJFj8aR25\n" +
+            "kpU/ZQTHl8Z9yrTLhr4VcMWMxqeOQUcUU27SgIuFvU9s/68OuaIhxyu6eohaGCLC\n" +
+            "wzFFRg8OlsUYuI1QtUEliIjmHOMDqSNIt093+SDV64osnHw5fpfy8V0zehEkd7QR\n" +
+            "t7Aq38ixCQyxCmNIDJeDCKJT+wwdLaKuw/4SEpR9sygSxZ3kG6kF4icsgYuiOCRx\n" +
+            "+DrS1wP9kcrQVWQ0bJbGzwxLZXCHaJsWE1Y17mQAO4Iv/9icqDkP3bZBU5GCgbNT\n" +
+            "JEP2GiUUPU3nL41Tlq03+iDmkS2bpWCtFZmTgUg+1nJEb7PSCJ9VcoflOOFgX/ku\n" +
+            "TQCJWwhsgyOneEZAg7PpzOj2msxA9RWI88FzRnX/zyjWEpdUCVJ85hFw8u+UZ7k1\n" +
+            "eF37oOpgNxQMJ+/ey7huneTzyhpFz/TqJpfMmwaGbPL6zmPLAMQalIPQj+68zlcX\n" +
+            "qyeKVbZU74Vm051kXb/3qs6CeUpT4HrY3UmHWLvOdNkCAwEAAaOCAiUwggIhMB8G\n" +
+            "A1UdIwQYMBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAn\n" +
+            "BggrBgEFBQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUF\n" +
+            "BzAChiFodHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAE\n" +
+            "ggElMIIBITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6\n" +
+            "Ly9yZXBvc2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRy\n" +
+            "dXN0IENlcnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kg\n" +
+            "VFMgMTAyIDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlv\n" +
+            "biBieSBDU1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRh\n" +
+            "IG9yIEVudGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAI\n" +
+            "BgYEAI96AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5s\n" +
+            "dS9MVEdRQ0EzLmNybDARBgNVHQ4ECgQISND+8GZyXrcwDgYDVR0PAQH/BAQDAgTw\n" +
+            "MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAA54w2kGy+hJsYSyrQ5C\n" +
+            "ft0rasUHQviEiy31H2Z1lh4yEPLiuUsaepdzG4bov/J1RewX1fL7fvErraKK7nNr\n" +
+            "ioAXNElHtC0wfxGx0xGaCz7xsZIDFgpzyPqS+vd8VKbRCOY66AI+3aPiatCsk+BM\n" +
+            "Hp9GwW3B1e5EOgXiWVNxzYFtav5QSAj28IEV7ZuN2BIiU+phawRaoFy+4glMB7zE\n" +
+            "J5AM/Zfi50Q85ljy1kWUueFE3VNDafAUGOF5gTHvkKqj6LznUkqcT8m96Wd0IbF2\n" +
+            "BLYjnKPF6lGJsivErGqMwQIhlUUMkRQ13/hftL12rIiSjC1C/6cnbxOjWEOGnler\n" +
+            "Qn2zu2OTGnnrYxp/hojdZggb5Yt9mkM3EmyuqP1W4g0xtMv9q97swm/fHz/rDh8T\n" +
+            "MqrEOJzz284IM0DXjXq1wkmsZ/6/ueCyf0oBN0csvYspZKmLAydZ+jZmjdKKxX+N\n" +
+            "dreauHgOq1knLHkMb/YIyA+Oh6SBlNXL4Iae8APQcRGnylHQ1lc/YHTqWh8N1tmn\n" +
+            "no5r1kVJBYYtkI3oufaLtP7JIazteZlqTN+tubMJhO4xGgt6bqEpQiid9r3UnIjR\n" +
+            "esLYxXS5qRwSoOSleXT98H75+Ok1WR3ciD4exBR8/KcUtDITvDJhkBHnRHm40jFs\n" +
+            "5UbHFf98S6G9dqzsqW8+2Bpn\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: T=Private Person, SERIALNUMBER=00100918135105608625,
+    // GIVENNAME=TokenPRIREV, SURNAME=Test, CN=TokenPRIREV Test, C=LU
+    // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+    // Serial number: 3814b8
+    // Valid from: Wed Jul 10 04:36:48 PDT 2019 until: Sun Jul 10 04:36:48 PDT 2022
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIG+DCCBOCgAwIBAgIDOBS4MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" +
+            "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" +
+            "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjQ4WhcNMjIwNzEwMTEzNjQ4\n" +
+            "WjCBhTELMAkGA1UEBhMCTFUxGTAXBgNVBAMTEFRva2VuUFJJUkVWIFRlc3QxDTAL\n" +
+            "BgNVBAQTBFRlc3QxFDASBgNVBCoTC1Rva2VuUFJJUkVWMR0wGwYDVQQFExQwMDEw\n" +
+            "MDkxODEzNTEwNTYwODYyNTEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24wggGiMA0G\n" +
+            "CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCcm7y4c/D58u6g3m6HGdfiqDXa2yEl\n" +
+            "H2cAeSb85fsAX08iXfa/U/kmFqqycwp2nsJdfor6HEEqHsmozyjjIWHDEsq+cUre\n" +
+            "SO6d2Ag29MrxsAWZ1XAol40FcxNN+yEL9Xs5doqqcbz3OoKdxkoWVdYq3D7peizF\n" +
+            "OER4M2XA0KSLiKXDapDCfTVLE6qRG6Cn5mqnlqbUtkI6vSsda5mWLSNe4Qw/PIMw\n" +
+            "v7ZDn5dHeHoV6UpZC95Ole5vMQfjAOsy4nRc1zofQz7iPw4ClNzDQSuonaAKSk3Y\n" +
+            "1KjWPmHshb6BoANL+ce1KuWESKV3D5lBkVVLTeoBkWQu7ViJviF2HE5UoPRSGijO\n" +
+            "nmGOTZRsjOJXPe7/pEq9SQ477EufnSsoCj1cPCtaowbsO7oswzV/axKMhhZf6nU7\n" +
+            "0wd9xUuMgMRKBfi026mYK7pdxJ85qE8qKlqeNprje+g1sjxMDbMHARA427Px0IUJ\n" +
+            "mzIJk0ysAQvbqQVe8QQM/f+PH3mUkXR02H8CAwEAAaOCAiUwggIhMB8GA1UdIwQY\n" +
+            "MBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAnBggrBgEF\n" +
+            "BQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFo\n" +
+            "dHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAEggElMIIB\n" +
+            "ITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBv\n" +
+            "c2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRydXN0IENl\n" +
+            "cnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kgVFMgMTAy\n" +
+            "IDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlvbiBieSBD\n" +
+            "U1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRhIG9yIEVu\n" +
+            "dGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAIBgYEAI96\n" +
+            "AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5sdS9MVEdR\n" +
+            "Q0EzLmNybDARBgNVHQ4ECgQIS0KUXpWyku0wDgYDVR0PAQH/BAQDAgTwMAwGA1Ud\n" +
+            "EwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAFSnezuyeRO0sh9e8/1N+2RE6Uhb\n" +
+            "RIdLKmaS8hMOyUNBapnHfJAdOn7j767qWQjRop5VNCcv0zDOxAqApxFiz4gJdzBY\n" +
+            "FVrEVwYos8a3BHLXNxfwIWEJ6EjlqI2qI3NjqK8m4M8LTq4G94V2/MOFVpXeCLju\n" +
+            "r0s+XZep2Sk9J4ofUOc8Gp7IZNhPzIlfKQ+KhnWovde4bpL3zRpp4u7Y580XsBuN\n" +
+            "kow2Eg84tRzSVizmgLPuRbySHuMo1jGIP7F9FdtOC8VVSjntfCXSEQqOvpH4YZ8S\n" +
+            "V4qP17CQHPWW1kOHAyXpkAjU+6SOlmF76Adv9nQFTZ6DAnKqiuxmi8EVCv96aFD7\n" +
+            "Ih+zBF7kj7fghPjUzsVdB6gI4VwuFCXEaAfWlxJS67s1hKnsCyqX3cu+Gnq9aRt+\n" +
+            "08iaTVEdrKL95AYYobVbnGJ7bH87SpenjLL+CDctXNNDlpJZ8eRYcQe+Q4dg+8L8\n" +
+            "X8tkXBeRbiZD1U7XwVBnKF6sJmhA4F/h/EJzwX0lp7EU6EO91bSiwD2NFVs+64UR\n" +
+            "9lftfFFm5In2N3vjDR/3nrCf3Jq9f0g7bTrNJmo+hc0+fD+zlAhZAx+ii2xE1cY1\n" +
+            "KLH2zXNzPUgIqYGdVQwn1TUFJN8JgGKsXwc+P51nEpgf6JVyK1m7EtVGtr9gF7DI\n" +
+            "P+4VSqTbTp4/l5n0\n" +
+            "-----END CERTIFICATE-----";
+
+    public static void main(String[] args) throws Exception {
+
+        ValidatePathWithParams pathValidator = new ValidatePathWithParams(null);
+
+        if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) {
+            pathValidator.enableCRLCheck();
+        } else {
+            // OCSP check by default
+            pathValidator.enableOCSPCheck();
+        }
+
+        // Validate valid
+        pathValidator.validate(new String[]{VALID, INT},
+                ValidatePathWithParams.Status.GOOD, null, System.out);
+
+        // Validate Revoked
+        pathValidator.validate(new String[]{REVOKED, INT},
+                ValidatePathWithParams.Status.REVOKED,
+                "Wed Jul 10 04:48:49 PDT 2019", System.out);
+    }
+}
diff --git a/test/sun/misc/IOUtils/ReadAllBytes.java b/test/sun/misc/IOUtils/ReadAllBytes.java
new file mode 100644
index 0000000..440aad0
--- /dev/null
+++ b/test/sun/misc/IOUtils/ReadAllBytes.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Random;
+
+import jdk.testlibrary.RandomFactory;
+
+import sun.misc.IOUtils;
+
+/*
+ * @test
+ * @bug 8080835 8193832
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @run main ReadAllBytes
+ * @summary Basic test for IOUtils.readAllBytes
+ * @key randomness
+ */
+
+public class ReadAllBytes {
+
+    private static Random generator = RandomFactory.getRandom();
+
+    public static void main(String[] args) throws IOException {
+        test(new byte[]{});
+        test(new byte[]{1, 2, 3});
+        test(createRandomBytes(1024));
+        for (int shift : new int[] {13, 14, 15, 17}) {
+            for (int offset : new int[] {-1, 0, 1}) {
+                test(createRandomBytes((1 << shift) + offset));
+            }
+        }
+    }
+
+    static void test(byte[] expectedBytes) throws IOException {
+        int expectedLength = expectedBytes.length;
+        WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(expectedBytes));
+        byte[] readBytes = IOUtils.readAllBytes(in);
+
+        int x;
+        byte[] tmp = new byte[10];
+        check((x = in.read()) == -1,
+              "Expected end of stream from read(), got " + x);
+        check((x = in.read(tmp)) == -1,
+              "Expected end of stream from read(byte[]), got " + x);
+        check((x = in.read(tmp, 0, tmp.length)) == -1,
+              "Expected end of stream from read(byte[], int, int), got " + x);
+        check(IOUtils.readAllBytes(in).length == 0,
+              "Expected readAllBytes to return empty byte array");
+        check(expectedLength == readBytes.length,
+              "Expected length " + expectedLength + ", got " + readBytes.length);
+        check(Arrays.equals(expectedBytes, readBytes),
+              "Expected[" + expectedBytes + "], got:[" + readBytes + "]");
+        check(!in.isClosed(), "Stream unexpectedly closed");
+    }
+
+    static byte[] createRandomBytes(int size) {
+        byte[] bytes = new byte[size];
+        generator.nextBytes(bytes);
+        return bytes;
+    }
+
+    static void check(boolean cond, Object ... failedArgs) {
+        if (cond)
+            return;
+        StringBuilder sb = new StringBuilder();
+        for (Object o : failedArgs)
+            sb.append(o);
+        throw new RuntimeException(sb.toString());
+    }
+
+    static class WrapperInputStream extends FilterInputStream {
+        private boolean closed;
+        WrapperInputStream(InputStream in) { super(in); }
+        @Override public void close() throws IOException { closed = true; in.close(); }
+        boolean isClosed() { return closed; }
+    }
+}
diff --git a/test/sun/misc/IOUtils/ReadNBytes.java b/test/sun/misc/IOUtils/ReadNBytes.java
new file mode 100644
index 0000000..96ae6c3
--- /dev/null
+++ b/test/sun/misc/IOUtils/ReadNBytes.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Random;
+import jdk.testlibrary.RandomFactory;
+
+import sun.misc.IOUtils;
+
+/*
+ * @test
+ * @bug 8080835 8139206
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @run main ReadNBytes
+ * @summary Basic test for IOUtils.readNBytes
+ * @key randomness
+ */
+
+public class ReadNBytes {
+
+    private static Random generator = RandomFactory.getRandom();
+
+    public static void main(String[] args) throws IOException {
+        test(new byte[]{1, 2, 3});
+        test(createRandomBytes(1024));
+        for (int shift : new int[] {13, 15, 17}) {
+            for (int offset : new int[] {-1, 0, 1}) {
+                test(createRandomBytes((1 << shift) + offset));
+            }
+        }
+
+        test(-1);
+        test(0);
+        for (int shift : new int[] {13, 15, 17}) {
+            for (int offset : new int[] {-1, 0, 1}) {
+                test((1 << shift) + offset);
+            }
+        }
+    }
+
+    static void test(byte[] inputBytes) throws IOException {
+        int length = inputBytes.length;
+        WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(inputBytes));
+        byte[] readBytes = new byte[(length / 2) + 1];
+        int nread = IOUtils.readNBytes(in, readBytes, 0, readBytes.length);
+
+        int x;
+        byte[] tmp;
+        check(nread == readBytes.length,
+              "Expected number of bytes read: " + readBytes.length + ", got: " + nread);
+        check(Arrays.equals((tmp = Arrays.copyOf(inputBytes, nread)), readBytes),
+              "Expected[" + tmp + "], got:[" + readBytes + "]");
+        check(!in.isClosed(), "Stream unexpectedly closed");
+
+        // Read again
+        nread = IOUtils.readNBytes(in, readBytes, 0, readBytes.length);
+
+        check(nread == length - readBytes.length,
+              "Expected number of bytes read: " + (length - readBytes.length) + ", got: " + nread);
+        check(Arrays.equals((tmp = Arrays.copyOfRange(inputBytes, readBytes.length, length)),
+                            Arrays.copyOf(readBytes, nread)),
+              "Expected[" + tmp + "], got:[" + readBytes + "]");
+        // Expect end of stream
+        check((x = in.read()) == -1,
+              "Expected end of stream from read(), got " + x);
+        check((x = in.read(tmp)) == -1,
+              "Expected end of stream from read(byte[]), got " + x);
+        check((x = in.read(tmp, 0, tmp.length)) == -1,
+              "Expected end of stream from read(byte[], int, int), got " + x);
+        check((x = IOUtils.readNBytes(in, tmp, 0, tmp.length)) == 0,
+              "Expected end of stream, 0, from readNBytes(byte[], int, int), got " + x);
+        check(!in.isClosed(), "Stream unexpectedly closed");
+    }
+
+    static void test(int max) throws IOException {
+        byte[] subset1, subset2;
+        byte[] inputBytes = max <= 0 ? new byte[0] : createRandomBytes(max);
+        WrapperInputStream in =
+            new WrapperInputStream(new ByteArrayInputStream(inputBytes));
+
+        if (max < 0) {
+            try {
+                IOUtils.readNBytes(in, max);
+                check(false, "Expected IllegalArgumentException not thrown");
+            } catch (IllegalArgumentException iae) {
+                return;
+            }
+        } else if (max == 0) {
+            int x;
+            check((x = IOUtils.readNBytes(in, max).length) == 0,
+                  "Expected zero bytes, got " + x);
+            return;
+        }
+
+        int off = Math.toIntExact(in.skip(generator.nextInt(max/2)));
+        int len = generator.nextInt(max - 1 - off);
+        byte[] readBytes = IOUtils.readNBytes(in, len);
+        check(readBytes.length == len,
+              "Expected " + len + " bytes, got " + readBytes.length);
+        subset1 = Arrays.copyOfRange(inputBytes, off, off + len);
+        subset2 = Arrays.copyOfRange(readBytes, 0, len);
+        check(Arrays.equals(subset1, subset2), "Expected[" + subset1 +
+              "], got:[" + readBytes + "]");
+
+        int remaining = max - (off + len);
+        readBytes = IOUtils.readNBytes(in, remaining);
+        check(readBytes.length == remaining,
+              "Expected " + remaining + "bytes, got " + readBytes.length);
+        subset1 = Arrays.copyOfRange(inputBytes, off + len, max);
+        subset2 = Arrays.copyOfRange(readBytes, 0, remaining);
+        check(Arrays.equals(subset1, subset2), "Expected[" + subset1 +
+          "], got:[" + readBytes + "]");
+
+        check(!in.isClosed(), "Stream unexpectedly closed");
+    }
+
+    static byte[] createRandomBytes(int size) {
+        byte[] bytes = new byte[size];
+        generator.nextBytes(bytes);
+        return bytes;
+    }
+
+    static void check(boolean cond, Object ... failedArgs) {
+        if (cond)
+            return;
+        StringBuilder sb = new StringBuilder();
+        for (Object o : failedArgs)
+            sb.append(o);
+        throw new RuntimeException(sb.toString());
+    }
+
+
+    static class WrapperInputStream extends FilterInputStream {
+        private boolean closed;
+        WrapperInputStream(InputStream in) { super(in); }
+        @Override public void close() throws IOException { closed = true; in.close(); }
+        boolean isClosed() { return closed; }
+    }
+}
diff --git a/test/sun/misc/URLClassPath/JarClassPathFileEntry.java b/test/sun/misc/URLClassPath/JarClassPathFileEntry.java
new file mode 100644
index 0000000..6f57ec5
--- /dev/null
+++ b/test/sun/misc/URLClassPath/JarClassPathFileEntry.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import jdk.testlibrary.InMemoryJavaCompiler;
+import jdk.testlibrary.JarUtils;
+
+/*
+ * @test
+ * @bug 8216401
+ * @summary Test loading of JAR Class-Path entry with file: scheme
+ * @library /lib/testlibrary
+ *
+ * @run main/othervm JarClassPathFileEntry
+ * @run main/othervm -Djdk.net.URLClassPath.disableClassPathURLCheck=true JarClassPathFileEntry
+ * @run main/othervm -Djdk.net.URLClassPath.disableClassPathURLCheck=false JarClassPathFileEntry
+ */
+
+public class JarClassPathFileEntry {
+    private final static boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows");
+
+    private final static String TEST_CLASSES = System.getProperty("test.classes");
+    private final static String OTHER_DIR = TEST_CLASSES + "/OTHER/";
+
+    private final static Path OTHER_JAR_PATH = Paths.get(OTHER_DIR, "Other.jar");
+    private final static Path CONTEXT_JAR_PATH = Paths.get(TEST_CLASSES, "Context.jar");
+
+    public static void main(String[] args) throws Throwable {
+        // Create Other.class in OTHER_DIR, off the default classpath
+        byte klassbuf[] = InMemoryJavaCompiler.compile("Other",
+                                                       "public class Other {}");
+        ClassFileInstaller.writeClassToDisk("Other", klassbuf, OTHER_DIR);
+
+        // Create Other.jar in OTHER_DIR
+        JarUtils.createJarFile(OTHER_JAR_PATH,
+                               Paths.get(OTHER_DIR),
+                               Paths.get(OTHER_DIR, "Other.class"));
+
+        // Create Context.class
+        klassbuf = InMemoryJavaCompiler.compile("Context",
+                                                "public class Context {}");
+        ClassFileInstaller.writeClassToDisk("Context", klassbuf, TEST_CLASSES);
+
+        // Create Context.jar w/ "file:" entry for Other.jar
+        Manifest mf = new Manifest();
+        Attributes attrs = mf.getMainAttributes();
+        attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+
+        String classPathEntry = "file:" + (IS_WINDOWS ? toUnixPath(OTHER_JAR_PATH.toString())
+                                                      :            OTHER_JAR_PATH.toString());
+        attrs.put(Attributes.Name.CLASS_PATH, classPathEntry);
+
+        System.out.println("Creating Context.jar with Class-Path: " + classPathEntry);
+        JarUtils.createJarFile(CONTEXT_JAR_PATH, mf,
+                               Paths.get(TEST_CLASSES),
+                               Paths.get(TEST_CLASSES, "Context.class"));
+
+        // Use URLClassLoader w/ Context.jar to load Other.class, which will
+        // load via the Class-Path entry
+        URL url = CONTEXT_JAR_PATH.toUri().toURL();
+        URLClassLoader ucl = new URLClassLoader(new URL[]{ url },
+                                                null); // don't delegate to App CL
+        Class<?> otherClass = Class.forName("Other", true, ucl); // ClassNotFoundException -> fail
+        System.out.println("Loaded: " + otherClass);
+    }
+
+    /* Convert a Windows path to a unix-style path, and remove any drive letter */
+    private static String toUnixPath(String orig) {
+        String retVal = new File(orig).toURI().getPath();
+        int colonAt = retVal.indexOf(':');
+
+        if (colonAt != -1 && colonAt < 3) {
+            retVal = retVal.substring(colonAt + 1); // Start after the drive letter
+        }
+        return retVal;
+    }
+}
diff --git a/test/sun/net/www/B8185898.java b/test/sun/net/www/B8185898.java
new file mode 100644
index 0000000..67f3998
--- /dev/null
+++ b/test/sun/net/www/B8185898.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2019, 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 8185898
+ * @library /lib/testlibrary
+ * @run main/othervm B8185898
+ * @summary setRequestProperty(key, null) results in HTTP header without colon in request
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+import java.util.Collections;
+
+import jdk.testlibrary.net.URIBuilder;
+import sun.net.www.MessageHeader;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/*
+ * Test checks that MessageHeader with key != null and value == null is set correctly
+ * and printed according to HTTP standard in the format <key>: <value>
+ * */
+public class B8185898 {
+
+    static HttpServer server;
+    static final String RESPONSE_BODY = "Test response body";
+    static final String H1 = "X-header1";
+    static final String H2 = "X-header2";
+    static final String VALUE = "This test value should appear";
+    static final List<String> oneList = Arrays.asList(VALUE);
+    static final List<String> zeroList = Arrays.asList("");
+    static int port;
+    static URL url;
+    static volatile Map<String, List<String>> headers;
+
+    static class Handler implements HttpHandler {
+
+        public void handle(HttpExchange t) throws IOException {
+            InputStream is = t.getRequestBody();
+            InetSocketAddress rem = t.getRemoteAddress();
+            headers = t.getRequestHeaders();    // Get request headers on the server side
+            while(is.read() != -1){}
+            is.close();
+
+            OutputStream os = t.getResponseBody();
+            t.sendResponseHeaders(200, RESPONSE_BODY.length());
+            os.write(RESPONSE_BODY.getBytes(UTF_8));
+            t.close();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        ExecutorService exec = Executors.newCachedThreadPool();
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+
+        try {
+            InetSocketAddress addr = new InetSocketAddress(loopback, 0);
+            server = HttpServer.create(addr, 100);
+            HttpHandler handler = new Handler();
+            HttpContext context = server.createContext("/", handler);
+            server.setExecutor(exec);
+            server.start();
+
+            port = server.getAddress().getPort();
+            System.out.println("Server on port: " + port);
+            url = URIBuilder.newBuilder()
+                    .scheme("http")
+                    .loopback()
+                    .port(port)
+                    .path("/foo")
+                    .toURLUnchecked();
+            System.out.println("URL: " + url);
+            testMessageHeader();
+            testMessageHeaderMethods();
+            testURLConnectionMethods();
+        } finally {
+            server.stop(0);
+            System.out.println("After server shutdown");
+            exec.shutdown();
+        }
+    }
+
+    // Test message header with malformed message header and fake request line
+    static void testMessageHeader() {
+        final String badHeader = "This is not a request line for HTTP/1.1";
+        final String fakeRequestLine = "This /is/a/fake/status/line HTTP/2.0";
+        final String expectedHeaders = fakeRequestLine + "\r\n"
+                + H1 + ": " + VALUE + "\r\n"
+                + H2 + ": " + VALUE + "\r\n"
+                + badHeader + ":\r\n\r\n";
+
+        MessageHeader header = new MessageHeader();
+        header.add(H1, VALUE);
+        header.add(H2, VALUE);
+        header.add(badHeader, null);
+        header.prepend(fakeRequestLine, null);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        header.print(new PrintStream(out));
+
+        if (!out.toString().equals(expectedHeaders)) {
+            throw new AssertionError("FAILED: expected: "
+                    + expectedHeaders + "\nReceived: " + out.toString());
+        } else {
+            System.out.println("PASSED: ::print returned correct "
+                    + "status line and headers:\n" + out.toString());
+        }
+    }
+
+    // Test MessageHeader::print, ::toString, implicitly testing that
+    // MessageHeader::mergeHeader formats headers correctly for responses
+    static void testMessageHeaderMethods() throws IOException {
+        // {{inputString1, expectedToString1, expectedPrint1}, {...}}
+        String[][] strings = {
+                {"HTTP/1.1 200 OK\r\n"
+                        + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+                        + "Connection: keep-alive\r\n"
+                        + "Host: 127.0.0.1:12345\r\n"
+                        + "User-agent: Java/12\r\n\r\nfoooo",
+                "pairs: {null: HTTP/1.1 200 OK}"
+                        + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"
+                        + "{Connection: keep-alive}"
+                        + "{Host: 127.0.0.1:12345}"
+                        + "{User-agent: Java/12}",
+                "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+                        + "Connection: keep-alive\r\n"
+                        + "Host: 127.0.0.1:12345\r\n"
+                        + "User-agent: Java/12\r\n\r\n"},
+                {"HTTP/1.1 200 OK\r\n"
+                        + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+                        + "Connection: keep-alive\r\n"
+                        + "Host: 127.0.0.1:12345\r\n"
+                        + "User-agent: Java/12\r\n"
+                        + "X-Header:\r\n\r\n",
+                "pairs: {null: HTTP/1.1 200 OK}"
+                        + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"
+                        + "{Connection: keep-alive}"
+                        + "{Host: 127.0.0.1:12345}"
+                        + "{User-agent: Java/12}"
+                        + "{X-Header: }",
+                "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+                        + "Connection: keep-alive\r\n"
+                        + "Host: 127.0.0.1:12345\r\n"
+                        + "User-agent: Java/12\r\n"
+                        + "X-Header: \r\n\r\n"},
+        };
+
+        System.out.println("Test custom message headers");
+        for (String[] s : strings) {
+            // Test MessageHeader::toString
+            MessageHeader header = new MessageHeader(
+                    new ByteArrayInputStream(s[0].getBytes(ISO_8859_1)));
+            if (!header.toString().endsWith(s[1])) {
+                throw new AssertionError("FAILED: expected: "
+                        + s[1] + "\nReceived: " + header);
+            } else {
+                System.out.println("PASSED: ::toString returned correct "
+                        + "status line and headers:\n" + header);
+            }
+
+            // Test MessageHeader::print
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            header.print(new PrintStream(out));
+            if (!out.toString().equals(s[2])) {
+                throw new AssertionError("FAILED: expected: "
+                        + s[2] + "\nReceived: " + out.toString());
+            } else {
+                System.out.println("PASSED: ::print returned correct "
+                        + "status line and headers:\n" + out.toString());
+            }
+        }
+    }
+
+    // Test methods URLConnection::getRequestProperties,
+    // ::getHeaderField, ::getHeaderFieldKey
+    static void testURLConnectionMethods() throws IOException {
+        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
+        urlConn.setRequestProperty(H1, "");
+        urlConn.setRequestProperty(H1, VALUE);
+        urlConn.setRequestProperty(H2, null);    // Expected to contain ':' between key and value
+        Map<String, List<String>> props = urlConn.getRequestProperties();
+        Map<String, List<String>> expectedMap = new HashMap<String, List<String>>();
+        expectedMap.put(H1, oneList);
+        expectedMap.put(H2, Arrays.asList((String)null));
+
+        // Test request properties
+        System.out.println("Client request properties");
+        StringBuilder sb = new StringBuilder();
+        props.forEach((k, v) -> sb.append(k + ": "
+                + v.stream().collect(Collectors.joining()) + "\n"));
+        System.out.println(sb);
+
+        if (!props.equals(expectedMap)) {
+            throw new AssertionError("Unexpected properties returned: "
+                    + props);
+        } else {
+            System.out.println("Properties returned as expected");
+        }
+
+        // Test header fields
+        String headerField = urlConn.getHeaderField(0);
+        if (!headerField.contains("200 OK")) {
+            throw new AssertionError("Expected headerField[0]: status line. "
+                    + "Received: " + headerField);
+        } else {
+            System.out.println("PASSED: headerField[0] contains status line: "
+                    + headerField);
+        }
+
+        String headerFieldKey = urlConn.getHeaderFieldKey(0);
+        if (headerFieldKey != null) {
+            throw new AssertionError("Expected headerFieldKey[0]: null. "
+                    + "Received: " + headerFieldKey);
+        } else {
+            System.out.println("PASSED: headerFieldKey[0] is null");
+        }
+
+        // Check that test request headers are included with correct format
+        try (
+                BufferedReader in = new BufferedReader(
+                        new InputStreamReader(urlConn.getInputStream()))
+        ) {
+            if (!headers.keySet().contains(H1)) {
+                throw new AssertionError("Expected key not found: "
+                        + H1 + ": " + VALUE);
+            } else if (!headers.get(H1).equals(oneList)) {
+                throw new AssertionError("Unexpected key-value pair: "
+                        + H1 + ": " + headers.get(H1));
+            } else {
+                System.out.println("PASSED: " + H1 + " included in request headers");
+            }
+
+            if (!headers.keySet().contains(H2)) {
+                throw new AssertionError("Expected key not found: "
+                        + H2 + ": ");
+                // Check that empty list is returned
+            } else if (!headers.get(H2).equals(zeroList)) {
+                throw new AssertionError("Unexpected key-value pair: "
+                        + H2 + ": " + headers.get(H2));
+            } else {
+                System.out.println("PASSED: " + H2 + " included in request headers");
+            }
+
+            String inputLine;
+            while ((inputLine = in.readLine()) != null) {
+                System.out.println(inputLine);
+            }
+        }
+    }
+}
diff --git a/test/sun/security/ec/SignatureDigestTruncate.java b/test/sun/security/ec/SignatureDigestTruncate.java
index a0ebbb2..18208fc 100644
--- a/test/sun/security/ec/SignatureDigestTruncate.java
+++ b/test/sun/security/ec/SignatureDigestTruncate.java
@@ -91,22 +91,25 @@
         String privateKeyStr, String msgStr, String kStr, String sigStr)
         throws Exception {
 
+        System.out.println("Testing " + alg + " with " + curveName);
+
         byte[] privateKey = Convert.hexStringToByteArray(privateKeyStr);
         byte[] msg = Convert.hexStringToByteArray(msgStr);
         byte[] k = Convert.hexStringToByteArray(kStr);
         byte[] expectedSig = Convert.hexStringToByteArray(sigStr);
 
-        AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
+        AlgorithmParameters params =
+            AlgorithmParameters.getInstance("EC", "SunEC");
         params.init(new ECGenParameterSpec(curveName));
         ECParameterSpec ecParams =
             params.getParameterSpec(ECParameterSpec.class);
 
-        KeyFactory kf = KeyFactory.getInstance("EC");
+        KeyFactory kf = KeyFactory.getInstance("EC", "SunEC");
         BigInteger s = new BigInteger(1, privateKey);
         ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(s, ecParams);
         PrivateKey privKey = kf.generatePrivate(privKeySpec);
 
-        Signature sig = Signature.getInstance(alg);
+        Signature sig = Signature.getInstance(alg, "SunEC");
         sig.initSign(privKey, new FixedRandom(k));
         sig.update(msg);
         byte[] computedSig = sig.sign();
diff --git a/test/sun/security/krb5/auto/Addresses.java b/test/sun/security/krb5/auto/Addresses.java
new file mode 100644
index 0000000..0bd62e4
--- /dev/null
+++ b/test/sun/security/krb5/auto/Addresses.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031111
+ * @summary fix krb5 caddr
+ * @compile -XDignore.symbol.file Addresses.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Addresses
+ */
+
+import sun.security.krb5.Config;
+
+import javax.security.auth.kerberos.KerberosTicket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+
+public class Addresses {
+
+    public static void main(String[] args) throws Exception {
+
+        KDC.saveConfig(OneKDC.KRB5_CONF, new OneKDC(null),
+                "noaddresses = false",
+                "extra_addresses = 10.0.0.10, 10.0.0.11 10.0.0.12");
+        Config.refresh();
+
+        KerberosTicket ticket =
+                Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false)
+                        .s().getPrivateCredentials(KerberosTicket.class)
+                        .iterator().next();
+
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        InetAddress extra1 = InetAddress.getByName("10.0.0.10");
+        InetAddress extra2 = InetAddress.getByName("10.0.0.11");
+        InetAddress extra3 = InetAddress.getByName("10.0.0.12");
+
+        boolean loopbackFound = false;
+        boolean extra1Found = false;
+        boolean extra2Found = false;
+        boolean extra3Found = false;
+        boolean networkFound = false;
+
+        for (InetAddress ia: ticket.getClientAddresses()) {
+            System.out.println(ia);
+            if (ia.equals(loopback)) {
+                loopbackFound = true;
+                System.out.println("  loopback found");
+            } else if (ia.equals(extra1)) {
+                extra1Found = true;
+                System.out.println("  extra1 found");
+            } else if (ia.equals(extra2)) {
+                extra2Found = true;
+                System.out.println("  extra2 found");
+            } else if (ia.equals(extra3)) {
+                extra3Found = true;
+                System.out.println("  extra3 found");
+            } else if (ia instanceof Inet4Address) {
+                networkFound = true;
+                System.out.println("  another address (" + ia +
+                        "), assumed real network");
+            }
+        }
+
+        if (!loopbackFound || !networkFound
+                || !extra1Found || !extra2Found || !extra3Found ) {
+            throw new Exception();
+        }
+    }
+}
diff --git a/test/sun/security/krb5/auto/Basic.java b/test/sun/security/krb5/auto/Basic.java
index 7ec3873..cc934ff 100644
--- a/test/sun/security/krb5/auto/Basic.java
+++ b/test/sun/security/krb5/auto/Basic.java
@@ -23,10 +23,12 @@
 
 /*
  * @test
- * @bug 7152176
+ * @bug 7152176 8201627
  * @summary More krb5 tests
  * @compile -XDignore.symbol.file Basic.java
- * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Basic
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock
+ *      -Dsun.security.krb5.acceptor.sequence.number.nonmutual=zero
+ *      Basic
  */
 
 import sun.security.jgss.GSSUtil;
@@ -45,6 +47,7 @@
 
         c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
         c.x().requestCredDeleg(true);
+        c.x().requestMutualAuth(false);
         s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
 
         Context.handshake(c, s);
diff --git a/test/sun/security/krb5/auto/BasicKrb5Test.java b/test/sun/security/krb5/auto/BasicKrb5Test.java
index ade0b54..f18ae16 100644
--- a/test/sun/security/krb5/auto/BasicKrb5Test.java
+++ b/test/sun/security/krb5/auto/BasicKrb5Test.java
@@ -79,7 +79,7 @@
         String etype = null;
         for (String arg: args) {
             if (arg.equals("-s")) Context.usingStream = true;
-            else if(arg.equals("-C")) conf = false;
+            else if (arg.equals("-C")) conf = false;
             else etype = arg;
         }
 
diff --git a/test/sun/security/krb5/auto/BasicProc.java b/test/sun/security/krb5/auto/BasicProc.java
index bcc3cd0..50f65ea 100644
--- a/test/sun/security/krb5/auto/BasicProc.java
+++ b/test/sun/security/krb5/auto/BasicProc.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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,180 +23,306 @@
 
 /*
  * @test
- * @bug 8009977
- * @summary A test library to launch multiple Java processes
- * @library ../../../../java/security/testlibrary/
+ * @bug 8009977 8186884 8201627
+ * @summary A test to launch multiple Java processes using either Java GSS
+ *          or native GSS
+ * @library ../../../../java/security/testlibrary /lib/testlibrary
  * @compile -XDignore.symbol.file BasicProc.java
- * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock BasicProc
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock BasicProc launcher
  */
 
-import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.PropertyPermission;
+import java.util.Set;
+
+import jdk.testlibrary.Asserts;
 import org.ietf.jgss.Oid;
+import sun.security.krb5.Config;
 
 import javax.security.auth.PrivateCredentialPermission;
 
+/**
+ * Run this test automatically and test Java GSS with embedded KDC.
+ *
+ * Run with customized native.krb5.libs to test interop between Java GSS
+ * and native GSS, and native.kdc.path with a native KDC. For example,
+ * run the following command to test interop among Java, default native,
+ * MIT, and Heimdal krb5 libraries with the Heimdal KDC:
+ *
+ *    jtreg -Dnative.krb5.libs=j=,
+ *                             n=,
+ *                             k=/usr/local/krb5/lib/libgssapi_krb5.so,
+ *                             h=/space/install/heimdal/lib/libgssapi.so \
+ *          -Dnative.kdc.path=/usr/local/heimdal \
+ *          BasicProc.java
+ *
+ * Note: The first 4 lines should be concatenated to make a long system
+ * property value with no blank around ",". This comma-separated value
+ * has each element being name=libpath. The special name "j" means the
+ * Java library and libpath is ignored. Otherwise it means a native library,
+ * and libpath (can be empty) will be the value for the sun.security.jgss.lib
+ * system property. If this system property is not set, only the Java
+ * library will be tested.
+ */
+
 public class BasicProc {
 
-    static String CONF = "krb5.conf";
-    static String KTAB = "ktab";
+    private static final String CONF = "krb5.conf";
+    private static final String KTAB_S = "server.ktab";
+    private static final String KTAB_B = "backend.ktab";
+
+    private static final String HOST = "localhost";
+    private static final String SERVER = "server/" + HOST;
+    private static final String BACKEND = "backend/" + HOST;
+    private static final String USER = "user";
+    private static final char[] PASS = "password".toCharArray();
+    private static final String REALM = "REALM";
+
+    private static final int MSGSIZE = 1024;
+    private static final byte[] MSG = new byte[MSGSIZE];
+
     public static void main(String[] args) throws Exception {
-        String HOST = "localhost";
-        String SERVER = "server/" + HOST;
-        String BACKEND = "backend/" + HOST;
-        String USER = "user";
-        char[] PASS = "password".toCharArray();
-        String REALM = "REALM";
 
         Oid oid = new Oid("1.2.840.113554.1.2.2");
+        byte[] token, msg;
 
-        if (args.length == 0) {
-            System.setProperty("java.security.krb5.conf", CONF);
-            KDC kdc = KDC.create(REALM, HOST, 0, true);
-            kdc.addPrincipal(USER, PASS);
-            kdc.addPrincipalRandKey("krbtgt/" + REALM);
-            kdc.addPrincipalRandKey(SERVER);
-            kdc.addPrincipalRandKey(BACKEND);
+        switch (args[0]) {
+            case "launcher":
+                KDC kdc = KDC.create(REALM, HOST, 0, true);
+                try {
+                    kdc.addPrincipal(USER, PASS);
+                    kdc.addPrincipalRandKey("krbtgt/" + REALM);
+                    kdc.addPrincipalRandKey(SERVER);
+                    kdc.addPrincipalRandKey(BACKEND);
 
-            String cwd = System.getProperty("user.dir");
-            kdc.writeKtab(KTAB);
-            KDC.saveConfig(CONF, kdc, "forwardable = true");
+                    // Native lib might do some name lookup
+                    KDC.saveConfig(CONF, kdc,
+                            "dns_lookup_kdc = no",
+                            "ticket_lifetime = 1h",
+                            "dns_lookup_realm = no",
+                            "dns_canonicalize_hostname = false",
+                            "forwardable = true");
+                    System.setProperty("java.security.krb5.conf", CONF);
+                    Config.refresh();
+                    kdc.writeKtab(KTAB_S, false, SERVER);
+                    kdc.writeKtab(KTAB_B, false, BACKEND);
 
-            Proc pc = Proc.create("BasicProc")
-                    .args("client")
-                    .prop("java.security.krb5.conf", CONF)
-                    .prop("java.security.manager", "")
-                    .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
-                    .perm(new java.lang.RuntimePermission(
-                            "accessClassInPackage.sun.net.spi.nameservice"))
-                    .perm(new java.util.PropertyPermission(
-                            "sun.security.krb5.principal", "read"))
-                    .perm(new javax.security.auth.AuthPermission(
-                            "modifyPrincipals"))
-                    .perm(new javax.security.auth.AuthPermission(
-                            "modifyPrivateCredentials"))
-                    .perm(new javax.security.auth.AuthPermission("doAs"))
-                    .perm(new javax.security.auth.kerberos.ServicePermission(
-                            "krbtgt/" + REALM + "@" + REALM, "initiate"))
-                    .perm(new javax.security.auth.kerberos.ServicePermission(
-                            "server/localhost@" + REALM, "initiate"))
-                    .perm(new javax.security.auth.kerberos.DelegationPermission(
-                            "\"server/localhost@" + REALM + "\" " +
-                                    "\"krbtgt/" + REALM + "@" + REALM + "\""))
-                    .debug("C")
-                    .start();
-            Proc ps = Proc.create("BasicProc")
-                    .args("server")
-                    .prop("java.security.krb5.conf", CONF)
-                    .prop("java.security.manager", "")
-                    .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
-                    .perm(new java.lang.RuntimePermission(
-                            "accessClassInPackage.sun.net.spi.nameservice"))
-                    .perm(new java.util.PropertyPermission(
-                            "sun.security.krb5.principal", "read"))
-                    .perm(new javax.security.auth.AuthPermission(
-                            "modifyPrincipals"))
-                    .perm(new javax.security.auth.AuthPermission(
-                            "modifyPrivateCredentials"))
-                    .perm(new javax.security.auth.AuthPermission("doAs"))
-                    .perm(new PrivateCredentialPermission(
-                            "javax.security.auth.kerberos.KeyTab * \"*\"",
-                            "read"))
-                    .perm(new javax.security.auth.kerberos.ServicePermission(
-                            "server/localhost@" + REALM, "accept"))
-                    .perm(new java.io.FilePermission(
-                            cwd + File.separator + KTAB, "read"))
-                    .perm(new javax.security.auth.kerberos.ServicePermission(
-                            "backend/localhost@" + REALM, "initiate"))
-                    .debug("S")
-                    .start();
-            Proc pb = Proc.create("BasicProc")
-                    .args("backend")
-                    .prop("java.security.krb5.conf", CONF)
-                    .prop("java.security.manager", "")
-                    .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
-                    .perm(new java.lang.RuntimePermission(
-                            "accessClassInPackage.sun.net.spi.nameservice"))
-                    .perm(new java.util.PropertyPermission(
-                            "sun.security.krb5.principal", "read"))
-                    .perm(new javax.security.auth.AuthPermission(
-                            "modifyPrincipals"))
-                    .perm(new javax.security.auth.AuthPermission(
-                            "modifyPrivateCredentials"))
-                    .perm(new javax.security.auth.AuthPermission("doAs"))
-                    .perm(new PrivateCredentialPermission(
-                            "javax.security.auth.kerberos.KeyTab * \"*\"",
-                            "read"))
-                    .perm(new javax.security.auth.kerberos.ServicePermission(
-                            "backend/localhost@" + REALM, "accept"))
-                    .perm(new java.io.FilePermission(
-                            cwd + File.separator + KTAB, "read"))
-                    .debug("B")
-                    .start();
+                    String[] tmp = System.getProperty("native.krb5.libs", "j=")
+                            .split(",");
 
-            // Client and server handshake
-            String token = pc.readData();
-            ps.println(token);
-            token = ps.readData();
-            pc.println(token);
-            // Server and backend handshake
-            token = ps.readData();
-            pb.println(token);
-            token = pb.readData();
-            ps.println(token);
-            // wrap/unwrap/getMic/verifyMic and plain text
-            token = ps.readData();
-            pb.println(token);
-            token = pb.readData();
-            ps.println(token);
-            token = pb.readData();
-            ps.println(token);
+                    // Library paths. The 1st one is always null which means
+                    // Java, "" means the default native lib.
+                    String[] libs = new String[tmp.length];
 
-            if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) {
-                throw new Exception();
-            }
-        } else if (args[0].equals("client")) {
-            Context c = Context.fromUserPass(USER, PASS, false);
-            c.startAsClient(SERVER, oid);
-            c.x().requestCredDeleg(true);
-            Proc.binOut(c.take(new byte[0]));
-            byte[] token = Proc.binIn();
-            c.take(token);
-        } else if (args[0].equals("server")) {
-            Context s = Context.fromUserKtab(SERVER, KTAB, true);
-            s.startAsServer(oid);
-            byte[] token = Proc.binIn();
-            token = s.take(token);
-            Proc.binOut(token);
-            Context s2 = s.delegated();
-            s2.startAsClient(BACKEND, oid);
-            Proc.binOut(s2.take(new byte[0]));
-            token = Proc.binIn();
-            s2.take(token);
-            byte[] msg = "Hello".getBytes();
-            Proc.binOut(s2.wrap(msg, true));
-            s2.verifyMic(Proc.binIn(), msg);
-            String in = Proc.textIn();
-            if (!in.equals("Hello")) {
-                throw new Exception();
-            }
-        } else if (args[0].equals("backend")) {
-            Context b = Context.fromUserKtab(BACKEND, KTAB, true);
-            b.startAsServer(oid);
-            byte[] token = Proc.binIn();
-            Proc.binOut(b.take(token));
-            byte[] msg = b.unwrap(Proc.binIn(), true);
-            Proc.binOut(b.getMic(msg));
-            Proc.textOut(new String(msg));
+                    // Names for each lib above. Use in file names.
+                    String[] names = new String[tmp.length];
+
+                    boolean hasNative = false;
+
+                    for (int i = 0; i < tmp.length; i++) {
+                        if (tmp[i].isEmpty()) {
+                            throw new Exception("Invalid native.krb5.libs");
+                        }
+                        String[] pair = tmp[i].split("=", 2);
+                        names[i] = pair[0];
+                        if (!pair[0].equals("j")) {
+                            libs[i] = pair.length > 1 ? pair[1] : "";
+                            hasNative = true;
+                        }
+                    }
+
+                    if (hasNative) {
+                        kdc.kinit(USER, "base.ccache");
+                    }
+
+                    // Try the same lib first
+                    for (int i = 0; i < libs.length; i++) {
+                        once(names[i] + names[i] + names[i],
+                                libs[i], libs[i], libs[i]);
+                    }
+
+                    for (int i = 0; i < libs.length; i++) {
+                        for (int j = 0; j < libs.length; j++) {
+                            for (int k = 0; k < libs.length; k++) {
+                                if (i != j || i != k) {
+                                    once(names[i] + names[j] + names[k],
+                                            libs[i], libs[j], libs[k]);
+                                }
+                            }
+                        }
+                    }
+                } finally {
+                    kdc.terminate();
+                }
+                break;
+            case "client":
+                Context c = args[1].equals("n") ?
+                        Context.fromThinAir() :
+                        Context.fromUserPass(USER, PASS, false);
+                c.startAsClient(SERVER, oid);
+                c.x().requestCredDeleg(true);
+                c.x().requestMutualAuth(true);
+                Proc.binOut(c.take(new byte[0])); // AP-REQ
+                c.take(Proc.binIn()); // AP-REP
+                Proc.binOut(c.wrap(MSG, true));
+                Proc.binOut(c.getMic(MSG));
+                break;
+            case "server":
+                Context s = args[1].equals("n") ?
+                        Context.fromThinAir() :
+                        Context.fromUserKtab(SERVER, KTAB_S, true);
+                s.startAsServer(oid);
+                token = Proc.binIn(); // AP-REQ
+                Proc.binOut(s.take(token)); // AP-REP
+                msg = s.unwrap(Proc.binIn(), true);
+                Asserts.assertTrue(Arrays.equals(msg, MSG));
+                s.verifyMic(Proc.binIn(), msg);
+                Context s2 = s.delegated();
+                s2.startAsClient(BACKEND, oid);
+                s2.x().requestMutualAuth(false);
+                Proc.binOut(s2.take(new byte[0])); // AP-REQ
+                msg = s2.unwrap(Proc.binIn(), true);
+                Asserts.assertTrue(Arrays.equals(msg, MSG));
+                s2.verifyMic(Proc.binIn(), msg);
+                break;
+            case "backend":
+                Context b = args[1].equals("n") ?
+                        Context.fromThinAir() :
+                        Context.fromUserKtab(BACKEND, KTAB_B, true);
+                b.startAsServer(oid);
+                token = b.take(Proc.binIn()); // AP-REQ
+                Asserts.assertTrue(token == null);
+                Proc.binOut(b.wrap(MSG, true));
+                Proc.binOut(b.getMic(MSG));
+                break;
         }
     }
-    // create a native server
-    private static Proc ns(Proc p) throws Exception {
-        return p
-            .env("KRB5_CONFIG", CONF)
-            .env("KRB5_KTNAME", KTAB)
-            .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
-            .prop("sun.security.jgss.native", "true")
-            .prop("javax.security.auth.useSubjectCredsOnly", "false")
-            .prop("sun.security.nativegss.debug", "true");
+
+    /**
+     * One test run.
+     *
+     * @param label test label
+     * @param lc lib of client
+     * @param ls lib of server
+     * @param lb lib of backend
+     */
+    private static void once(String label, String lc, String ls, String lb)
+            throws Exception {
+
+        Proc pc = proc(lc)
+                .args("client", lc == null ? "j" : "n")
+                .perm(new javax.security.auth.kerberos.ServicePermission(
+                        "krbtgt/" + REALM + "@" + REALM, "initiate"))
+                .perm(new javax.security.auth.kerberos.ServicePermission(
+                        SERVER + "@" + REALM, "initiate"))
+                .perm(new javax.security.auth.kerberos.DelegationPermission(
+                        "\"" + SERVER + "@" + REALM + "\" " +
+                                "\"krbtgt/" + REALM + "@" + REALM + "\""))
+                .debug(label + "-C");
+        if (lc == null) {
+            // for Krb5LoginModule::promptForName
+            pc.perm(new PropertyPermission("user.name", "read"));
+        } else {
+            Files.copy(Paths.get("base.ccache"), Paths.get(label + ".ccache"));
+            Set<PosixFilePermission> perms = new HashSet<>();
+            perms.add(PosixFilePermission.OWNER_READ);
+            perms.add(PosixFilePermission.OWNER_WRITE);
+            Files.setPosixFilePermissions(Paths.get(label + ".ccache"),
+                                          Collections.unmodifiableSet(perms));
+            pc.env("KRB5CCNAME", label + ".ccache");
+            // Do not try system ktab if ccache fails
+            pc.env("KRB5_KTNAME", "none");
+        }
+        pc.start();
+
+        Proc ps = proc(ls)
+                .args("server", ls == null ? "j" : "n")
+                .perm(new javax.security.auth.kerberos.ServicePermission(
+                        SERVER + "@" + REALM, "accept"))
+                .perm(new javax.security.auth.kerberos.ServicePermission(
+                        BACKEND + "@" + REALM, "initiate"))
+                .debug(label + "-S");
+        if (ls == null) {
+            ps.perm(new PrivateCredentialPermission(
+                    "javax.security.auth.kerberos.KeyTab * \"*\"", "read"))
+                .perm(new java.io.FilePermission(KTAB_S, "read"));
+        } else {
+            ps.env("KRB5_KTNAME", KTAB_S);
+        }
+        ps.start();
+
+        Proc pb = proc(lb)
+                .args("backend", lb == null ? "j" : "n")
+                .perm(new javax.security.auth.kerberos.ServicePermission(
+                        BACKEND + "@" + REALM, "accept"))
+                .debug(label + "-B");
+        if (lb == null) {
+            pb.perm(new PrivateCredentialPermission(
+                    "javax.security.auth.kerberos.KeyTab * \"*\"", "read"))
+                .perm(new java.io.FilePermission(KTAB_B, "read"));
+        } else {
+            pb.env("KRB5_KTNAME", KTAB_B);
+        }
+        pb.start();
+
+        // Client and server
+        ps.println(pc.readData()); // AP-REQ
+        pc.println(ps.readData()); // AP-REP
+
+        ps.println(pc.readData()); // KRB-PRIV
+        ps.println(pc.readData()); // KRB-SAFE
+
+        // Server and backend
+        pb.println(ps.readData()); // AP-REQ
+
+        ps.println(pb.readData()); // KRB-PRIV
+        ps.println(pb.readData()); // KRB-SAFE
+
+        if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) {
+            throw new Exception("Process failed");
+        }
+    }
+
+    /**
+     * A Proc for a child process.
+     *
+     * @param lib the library. Null is Java. "" is default native lib.
+     */
+    private static Proc proc(String lib) throws Exception {
+        Proc p = Proc.create("BasicProc")
+                .prop("java.security.manager", "")
+                .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
+                .perm(new javax.security.auth.AuthPermission("doAs"));
+        if (lib != null) {
+            p.env("KRB5_CONFIG", CONF)
+                    .env("KRB5_TRACE", "/dev/stderr")
+                    .prop("sun.security.jgss.native", "true")
+                    .prop("sun.security.jgss.lib", lib)
+                    .prop("javax.security.auth.useSubjectCredsOnly", "false")
+                    .prop("sun.security.nativegss.debug", "true");
+            int pos = lib.lastIndexOf('/');
+            if (pos > 0) {
+                p.env("LD_LIBRARY_PATH", lib.substring(0, pos));
+                p.env("DYLD_LIBRARY_PATH", lib.substring(0, pos));
+            }
+        } else {
+            p.perm(new java.util.PropertyPermission(
+                            "sun.security.krb5.principal", "read"))
+                            // For Krb5LoginModule::login.
+                    .perm(new java.lang.RuntimePermission(
+                            "accessClassInPackage.sun.net.spi.nameservice"))
+                    .perm(new javax.security.auth.AuthPermission(
+                            "modifyPrincipals"))
+                    .perm(new javax.security.auth.AuthPermission(
+                            "modifyPrivateCredentials"))
+                    .prop("sun.security.krb5.debug", "true")
+                    .prop("java.security.krb5.conf", CONF);
+        }
+        return p;
     }
 }
diff --git a/test/sun/security/krb5/auto/Context.java b/test/sun/security/krb5/auto/Context.java
index f664605..2c49153 100644
--- a/test/sun/security/krb5/auto/Context.java
+++ b/test/sun/security/krb5/auto/Context.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -22,14 +22,21 @@
  */
 
 import com.sun.security.auth.module.Krb5LoginModule;
-import java.security.Key;
+import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.security.Key;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.login.LoginContext;
@@ -40,6 +47,10 @@
 import org.ietf.jgss.GSSName;
 import org.ietf.jgss.MessageProp;
 import org.ietf.jgss.Oid;
+import sun.security.jgss.krb5.Krb5Util;
+import sun.security.krb5.Credentials;
+import sun.security.krb5.internal.ccache.CredentialsCache;
+
 import com.sun.security.jgss.ExtendedGSSContext;
 import com.sun.security.jgss.InquireType;
 import com.sun.security.jgss.AuthorizationDataEntry;
@@ -154,24 +165,36 @@
         Map<String, String> map = new HashMap<>();
         Map<String, Object> shared = new HashMap<>();
 
+        if (storeKey) {
+            map.put("storeKey", "true");
+        }
+
         if (pass != null) {
-            map.put("useFirstPass", "true");
-            shared.put("javax.security.auth.login.name", user);
-            shared.put("javax.security.auth.login.password", pass);
+            krb5.initialize(out.s, new CallbackHandler() {
+                @Override
+                public void handle(Callback[] callbacks)
+                        throws IOException, UnsupportedCallbackException {
+                    for (Callback cb: callbacks) {
+                        if (cb instanceof NameCallback) {
+                            ((NameCallback)cb).setName(user);
+                        } else if (cb instanceof PasswordCallback) {
+                            ((PasswordCallback)cb).setPassword(pass);
+                        }
+                    }
+                }
+            }, shared, map);
         } else {
             map.put("doNotPrompt", "true");
             map.put("useTicketCache", "true");
             if (user != null) {
                 map.put("principal", user);
             }
-        }
-        if (storeKey) {
-            map.put("storeKey", "true");
+            krb5.initialize(out.s, null, shared, map);
         }
 
-        krb5.initialize(out.s, null, shared, map);
         krb5.login();
         krb5.commit();
+
         return out;
     }
 
@@ -452,18 +475,21 @@
                     out = me.x.wrap(input, 0, input.length, p1);
                 }
                 System.out.println(printProp(p1));
+                if ((x.getConfState() && privacy) != p1.getPrivacy()) {
+                    throw new Exception("unexpected privacy status");
+                }
                 return out;
             }
         }, t);
     }
 
-    public byte[] unwrap(byte[] t, final boolean privacy)
+    public byte[] unwrap(byte[] t, final boolean privacyExpected)
             throws Exception {
         return doAs(new Action() {
             @Override
             public byte[] run(Context me, byte[] input) throws Exception {
-                System.out.printf("unwrap %s privacy from %s: ", privacy?"with":"without", me.name);
-                MessageProp p1 = new MessageProp(0, privacy);
+                System.out.printf("unwrap from %s", me.name);
+                MessageProp p1 = new MessageProp(0, true);
                 byte[] bytes;
                 if (usingStream) {
                     ByteArrayOutputStream os = new ByteArrayOutputStream();
@@ -473,6 +499,9 @@
                     bytes = me.x.unwrap(input, 0, input.length, p1);
                 }
                 System.out.println(printProp(p1));
+                if (p1.getPrivacy() != privacyExpected) {
+                    throw new Exception("Unexpected privacy: " + p1.getPrivacy());
+                }
                 return bytes;
             }
         }, t);
@@ -514,6 +543,10 @@
                             p1);
                 }
                 System.out.println(printProp(p1));
+                if (p1.isUnseqToken() || p1.isOldToken()
+                        || p1.isDuplicateToken() || p1.isGapToken()) {
+                    throw new Exception("Wrong sequence number detected");
+                }
                 return null;
             }
         }, t);
@@ -529,13 +562,27 @@
      * @param s2 the receiver
      * @throws java.lang.Exception If anything goes wrong
      */
-    static public void transmit(final String message, final Context s1,
+    static public void transmit(String message, final Context s1,
+                                final Context s2) throws Exception {
+        transmit(message.getBytes(), s1, s2);
+    }
+
+    /**
+     * Transmits a message from one Context to another. The sender wraps the
+     * message and sends it to the receiver. The receiver unwraps it, creates
+     * a MIC of the clear text and sends it back to the sender. The sender
+     * verifies the MIC against the message sent earlier.
+     * @param messageBytes the message
+     * @param s1 the sender
+     * @param s2 the receiver
+     * @throws java.lang.Exception If anything goes wrong
+     */
+    static public void transmit(byte[] messageBytes, final Context s1,
             final Context s2) throws Exception {
-        final byte[] messageBytes = message.getBytes();
         System.out.printf("-------------------- TRANSMIT from %s to %s------------------------\n",
                 s1.name, s2.name);
         byte[] wrapped = s1.wrap(messageBytes, true);
-        byte[] unwrapped = s2.unwrap(wrapped, true);
+        byte[] unwrapped = s2.unwrap(wrapped, s2.x.getConfState());
         if (!Arrays.equals(messageBytes, unwrapped)) {
             throw new Exception("wrap/unwrap mismatch");
         }
@@ -616,6 +663,32 @@
     }
 
     /**
+     * Saves the tickets to a ccache file.
+     *
+     * @param file pathname of the ccache file
+     * @return true if created, false otherwise.
+     */
+    public boolean ccache(String file) throws Exception {
+        Set<KerberosTicket> tickets
+                = s.getPrivateCredentials(KerberosTicket.class);
+        if (tickets != null && !tickets.isEmpty()) {
+            CredentialsCache cc = null;
+            for (KerberosTicket t : tickets) {
+                Credentials cred = Krb5Util.ticketToCreds(t);
+                if (cc == null) {
+                    cc = CredentialsCache.create(cred.getClient(), file);
+                }
+                cc.update(cred.toCCacheCreds());
+            }
+            if (cc != null) {
+                cc.save();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Handshake (security context establishment process) between two Contexts
      * @param c the initiator
      * @param s the acceptor
diff --git a/test/sun/security/krb5/auto/DiffSaltParams.java b/test/sun/security/krb5/auto/DiffSaltParams.java
new file mode 100644
index 0000000..275b827
--- /dev/null
+++ b/test/sun/security/krb5/auto/DiffSaltParams.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, 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 8186831
+ * @summary Kerberos ignores PA-DATA with a non-null s2kparams
+ * @compile -XDignore.symbol.file DiffSaltParams.java
+ * @run main/othervm -Dsun.security.krb5.debug=true -Dsun.net.spi.nameservice.provider.1=ns,mock DiffSaltParams
+ */
+
+public class DiffSaltParams {
+
+    public static void main(String[] args) throws Exception {
+
+        OneKDC kdc = new OneKDC(null).writeJAASConf();
+        kdc.addPrincipal("user1", "user1pass".toCharArray(),
+                "hello", new byte[]{0, 0, 1, 0});
+        kdc.addPrincipal("user2", "user2pass".toCharArray(),
+                "hello", null);
+        kdc.addPrincipal("user3", "user3pass".toCharArray(),
+                null, new byte[]{0, 0, 1, 0});
+        kdc.addPrincipal("user4", "user4pass".toCharArray());
+
+        Context.fromUserPass("user1", "user1pass".toCharArray(), true);
+        Context.fromUserPass("user2", "user2pass".toCharArray(), true);
+        Context.fromUserPass("user3", "user3pass".toCharArray(), true);
+        Context.fromUserPass("user4", "user4pass".toCharArray(), true);
+    }
+}
diff --git a/test/sun/security/krb5/auto/Forwarded.java b/test/sun/security/krb5/auto/Forwarded.java
new file mode 100644
index 0000000..0bdc3f5
--- /dev/null
+++ b/test/sun/security/krb5/auto/Forwarded.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031111
+ * @summary fix krb5 caddr
+ * @compile -XDignore.symbol.file Forwarded.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Forwarded
+ */
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.internal.KDCOptions;
+import sun.security.krb5.internal.KDCReqBody;
+import sun.security.krb5.internal.TGSReq;
+
+public class Forwarded {
+
+    public static void main(String[] args) throws Exception {
+
+        new OneKDC(null).setOption(KDC.Option.CHECK_ADDRESSES, true);
+
+        Context c;
+        c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        c.x().requestCredDeleg(true);
+
+        c.take(new byte[0]);
+    }
+}
diff --git a/test/sun/security/krb5/auto/KDC.java b/test/sun/security/krb5/auto/KDC.java
index 02a363d..0c5a891 100644
--- a/test/sun/security/krb5/auto/KDC.java
+++ b/test/sun/security/krb5/auto/KDC.java
@@ -27,19 +27,19 @@
 import java.net.*;
 import java.io.*;
 import java.lang.reflect.Method;
-import java.security.SecureRandom;
-import java.time.Instant;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalAmount;
-import java.time.temporal.TemporalUnit;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import sun.net.spi.nameservice.NameService;
 import sun.net.spi.nameservice.NameServiceDescriptor;
 import sun.security.krb5.*;
 import sun.security.krb5.internal.*;
 import sun.security.krb5.internal.ccache.CredentialsCache;
+import sun.security.krb5.internal.crypto.EType;
 import sun.security.krb5.internal.crypto.KeyUsage;
 import sun.security.krb5.internal.ktab.KeyTab;
 import sun.security.util.DerInputStream;
@@ -50,6 +50,11 @@
 
 /**
  * A KDC server.
+ *
+ * Note: By setting the system property native.kdc.path to a native
+ * krb5 installation, this class starts a native KDC with the
+ * given realm and host. It can also add new principals and save keytabs.
+ * Other features might not be available.
  * <p>
  * Features:
  * <ol>
@@ -127,13 +132,21 @@
  */
 public class KDC {
 
-    // Under the hood.
-
     public static final int DEFAULT_LIFETIME = 39600;
     public static final int DEFAULT_RENEWTIME = 86400;
 
-    // The random generator to generate random keys (including session keys)
-    private static SecureRandom secureRandom = new SecureRandom();
+    // What etypes the KDC supports. Comma-separated strings. Null for all.
+    // Please note native KDCs might use different names.
+    private static final String SUPPORTED_ETYPES
+            = System.getProperty("kdc.supported.enctypes");
+
+    // The native KDC
+    private final NativeKdc nativeKdc;
+
+    // The native KDC process
+    private Process kdcProc = null;
+
+    // Under the hood.
 
     // Principal db. principal -> pass. A case-insensitive TreeMap is used
     // so that even if the client provides a name with different case, the KDC
@@ -141,6 +154,25 @@
     private TreeMap<String,char[]> passwords = new TreeMap<>
             (String.CASE_INSENSITIVE_ORDER);
 
+    // Non default salts. Precisely, there should be different salts for
+    // different etypes, pretend they are the same at the moment.
+    private TreeMap<String,String> salts = new TreeMap<>
+            (String.CASE_INSENSITIVE_ORDER);
+
+    // Non default s2kparams for newer etypes. Precisely, there should be
+    // different s2kparams for different etypes, pretend they are the same
+    // at the moment.
+    private TreeMap<String,byte[]> s2kparamses = new TreeMap<>
+            (String.CASE_INSENSITIVE_ORDER);
+
+    // Alias for referrals.
+    private TreeMap<String,KDC> aliasReferrals = new TreeMap<>
+            (String.CASE_INSENSITIVE_ORDER);
+
+    // Alias for local resolution.
+    private TreeMap<String,PrincipalName> alias2Principals = new TreeMap<>
+            (String.CASE_INSENSITIVE_ORDER);
+
     // Realm name
     private String realm;
     // KDC
@@ -213,6 +245,10 @@
          * Sensitive accounts can never be delegated.
          */
         SENSITIVE_ACCOUNTS,
+        /**
+         * If true, will check if TGS-REQ contains a non-null addresses field.
+         */
+        CHECK_ADDRESSES,
     };
 
     //static {
@@ -223,7 +259,8 @@
      * A standalone KDC server.
      */
     public static void main(String[] args) throws Exception {
-        KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", 0, false);
+        int port = args.length > 0 ? Integer.parseInt(args[0]) : 0;
+        KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", port, false);
         kdc.addPrincipal("dummy", "bogus".toCharArray());
         kdc.addPrincipal("foo", "bar".toCharArray());
         kdc.addPrincipalRandKey("krbtgt/RABBIT.HOLE");
@@ -257,7 +294,8 @@
      * @return the running KDC instance
      * @throws java.io.IOException for any socket creation error
      */
-    public static KDC create(String realm, String kdc, int port, boolean asDaemon) throws IOException {
+    public static KDC create(String realm, String kdc, int port,
+                             boolean asDaemon) throws IOException {
         return new KDC(realm, kdc, port, asDaemon);
     }
 
@@ -297,26 +335,38 @@
      */
     public void writeKtab(String tab, boolean append, String... names)
             throws IOException, KrbException {
-        KeyTab ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
+        KeyTab ktab = null;
+        if (nativeKdc == null) {
+            ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
+        }
         Iterable<String> entries =
                 (names.length != 0) ? Arrays.asList(names): passwords.keySet();
         for (String name : entries) {
-            char[] pass = passwords.get(name);
-            int kvno = 0;
-            if (Character.isDigit(pass[pass.length-1])) {
-                kvno = pass[pass.length-1] - '0';
+            if (name.indexOf('@') < 0) {
+                name = name + "@" + realm;
             }
-            PrincipalName pn = new PrincipalName(name,
+            if (nativeKdc == null) {
+                char[] pass = passwords.get(name);
+                int kvno = 0;
+                if (Character.isDigit(pass[pass.length - 1])) {
+                    kvno = pass[pass.length - 1] - '0';
+                }
+                PrincipalName pn = new PrincipalName(name,
                         name.indexOf('/') < 0 ?
-                            PrincipalName.KRB_NT_UNKNOWN :
-                            PrincipalName.KRB_NT_SRV_HST);
-            ktab.addEntry(pn,
+                                PrincipalName.KRB_NT_UNKNOWN :
+                                PrincipalName.KRB_NT_SRV_HST);
+                ktab.addEntry(pn,
                         getSalt(pn),
                         pass,
                         kvno,
                         true);
+            } else {
+                nativeKdc.ktadd(name, tab);
+            }
         }
-        ktab.save();
+        if (nativeKdc == null) {
+            ktab.save();
+        }
     }
 
     /**
@@ -362,10 +412,36 @@
      * @param pass the password for the principal
      */
     public void addPrincipal(String user, char[] pass) {
+        addPrincipal(user, pass, null, null);
+    }
+
+    /**
+     * Adds a new principal to this realm with a given password.
+     * @param user the principal's name. For a service principal, use the
+     *        form of host/f.q.d.n
+     * @param pass the password for the principal
+     * @param salt the salt, or null if a default value will be used
+     * @param s2kparams the s2kparams, or null if a default value will be used
+     */
+    public void addPrincipal(
+            String user, char[] pass, String salt, byte[] s2kparams) {
         if (user.indexOf('@') < 0) {
             user = user + "@" + realm;
         }
-        passwords.put(user, pass);
+        if (nativeKdc != null) {
+            if (!user.equals("krbtgt/" + realm)) {
+                nativeKdc.addPrincipal(user, new String(pass));
+            }
+            passwords.put(user, new char[0]);
+        } else {
+            passwords.put(user, pass);
+            if (salt != null) {
+                salts.put(user, salt);
+            }
+            if (s2kparams != null) {
+                s2kparamses.put(user, s2kparams);
+            }
+        }
     }
 
     /**
@@ -461,12 +537,11 @@
      */
     public static void saveConfig(String file, KDC kdc, Object... more)
             throws IOException {
-        File f = new File(file);
         StringBuffer sb = new StringBuffer();
         sb.append("[libdefaults]\ndefault_realm = ");
         sb.append(kdc.realm);
         sb.append("\n");
-        for (Object o: more) {
+        for (Object o : more) {
             if (o instanceof String) {
                 sb.append(o);
                 sb.append("\n");
@@ -474,14 +549,12 @@
         }
         sb.append("\n[realms]\n");
         sb.append(kdc.realmLine());
-        for (Object o: more) {
+        for (Object o : more) {
             if (o instanceof KDC) {
-                sb.append(((KDC)o).realmLine());
+                sb.append(((KDC) o).realmLine());
             }
         }
-        FileOutputStream fos = new FileOutputStream(f);
-        fos.write(sb.toString().getBytes());
-        fos.close();
+        Files.write(Paths.get(file), sb.toString().getBytes());
     }
 
     /**
@@ -492,6 +565,29 @@
         return port;
     }
 
+    /**
+     * Register an alias name to be referred to a different KDC for
+     * resolution, according to RFC 6806.
+     * @param alias Alias name (i.e. user@REALM.COM).
+     * @param referredKDC KDC to which the alias is referred for resolution.
+     */
+    public void registerAlias(String alias, KDC referredKDC) {
+        aliasReferrals.remove(alias);
+        aliasReferrals.put(alias, referredKDC);
+    }
+
+    /**
+     * Register an alias to be resolved to a Principal Name locally,
+     * according to RFC 6806.
+     * @param alias Alias name (i.e. user@REALM.COM).
+     * @param user Principal Name to which the alias is resolved.
+     */
+    public void registerAlias(String alias, String user)
+            throws RealmException {
+        alias2Principals.remove(alias);
+        alias2Principals.put(alias, new PrincipalName(user));
+    }
+
     // Private helper methods
 
     /**
@@ -501,6 +597,7 @@
     private KDC(String realm, String kdc) {
         this.realm = realm;
         this.kdc = kdc;
+        this.nativeKdc = null;
     }
 
     /**
@@ -508,7 +605,9 @@
      */
     protected KDC(String realm, String kdc, int port, boolean asDaemon)
             throws IOException {
-        this(realm, kdc);
+        this.realm = realm;
+        this.kdc = kdc;
+        this.nativeKdc = NativeKdc.get(this);
         startServer(port, asDaemon);
     }
     /**
@@ -517,8 +616,9 @@
      */
     private static char[] randomPassword() {
         char[] pass = new char[32];
+        Random r = new Random();
         for (int i=0; i<31; i++)
-            pass[i] = (char)secureRandom.nextInt();
+            pass[i] = (char)('a' + r.nextInt(26));
         // The last char cannot be a number, otherwise, keyForUser()
         // believes it's a sign of kvno
         pass[31] = 'Z';
@@ -580,6 +680,9 @@
         if (p.getRealmString() == null) {
             pn = pn + "@" + getRealm();
         }
+        if (salts.containsKey(pn)) {
+            return salts.get(pn);
+        }
         if (passwords.containsKey(pn)) {
             try {
                 // Find the principal name with correct case.
@@ -597,6 +700,29 @@
     }
 
     /**
+     * Returns the s2kparams for the principal given the etype.
+     * @param p principal
+     * @param etype encryption type
+     * @return the s2kparams, might be null
+     */
+    protected byte[] getParams(PrincipalName p, int etype) {
+        switch (etype) {
+            case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
+            case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
+                String pn = p.toString();
+                if (p.getRealmString() == null) {
+                    pn = pn + "@" + getRealm();
+                }
+                if (s2kparamses.containsKey(pn)) {
+                    return s2kparamses.get(pn);
+                }
+                return new byte[] {0, 0, 0x10, 0};
+            default:
+                return null;
+        }
+    }
+
+    /**
      * Returns the key for a given principal of the given encryption type
      * @param p the principal
      * @param etype the encryption type
@@ -604,7 +730,7 @@
      * @return the key
      * @throws sun.security.krb5.KrbException for unknown/unsupported etype
      */
-    private EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
+    EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
             throws KrbException {
         try {
             // Do not call EncryptionKey.acquireSecretKeys(), otherwise
@@ -619,7 +745,7 @@
                 }
             }
             return new EncryptionKey(EncryptionKeyDotStringToKey(
-                    getPassword(p, server), getSalt(p), null, etype),
+                    getPassword(p, server), getSalt(p), getParams(p, etype), etype),
                     etype, kvno);
         } catch (KrbException ke) {
             throw ke;
@@ -668,17 +794,36 @@
                     " sends TGS-REQ for " +
                     service + ", " + tgsReq.reqBody.kdcOptions);
             KDCReqBody body = tgsReq.reqBody;
-            int[] eTypes = KDCReqBodyDotEType(body);
+            int[] eTypes = filterSupported(KDCReqBodyDotEType(body));
+            if (eTypes.length == 0) {
+                throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
+            }
             int e2 = eTypes[0];     // etype for outgoing session key
             int e3 = eTypes[0];     // etype for outgoing ticket
 
-            PAData[] pas = KDCReqDotPAData(tgsReq);
+            PAData[] pas = tgsReq.pAData;
 
             Ticket tkt = null;
             EncTicketPart etp = null;
 
             PrincipalName cname = null;
             boolean allowForwardable = true;
+            boolean isReferral = false;
+            if (body.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+                System.out.println(realm + "> verifying referral for " +
+                        body.sname.getNameString());
+                KDC referral = aliasReferrals.get(body.sname.getNameString());
+                if (referral != null) {
+                    service = new PrincipalName(
+                            PrincipalName.TGS_DEFAULT_SRV_NAME +
+                            PrincipalName.NAME_COMPONENT_SEPARATOR_STR +
+                            referral.getRealm(), PrincipalName.KRB_NT_SRV_INST,
+                            this.getRealm());
+                    System.out.println(realm + "> referral to " +
+                            referral.getRealm());
+                    isReferral = true;
+                }
+            }
 
             if (pas == null || pas.length == 0) {
                 throw new KrbException(Krb5.KDC_ERR_PADATA_TYPE_NOSUPP);
@@ -687,7 +832,6 @@
                 for (PAData pa: pas) {
                     if (pa.getType() == Krb5.PA_TGS_REQ) {
                         APReq apReq = new APReq(pa.getValue());
-                        EncryptedData ed = apReq.authenticator;
                         tkt = apReq.ticket;
                         int te = tkt.encPart.getEType();
                         EncryptionKey kkey = keyForUser(tkt.sname, te, true);
@@ -705,13 +849,14 @@
                             PAForUserEnc p4u = new PAForUserEnc(
                                     new DerValue(pa.getValue()), null);
                             forUserCName = p4u.name;
-                            System.out.println(realm + "> presenting a PA_FOR_USER "
+                            System.out.println(realm + "> See PA_FOR_USER "
                                     + " in the name of " + p4u.name);
                         }
                     }
                 }
                 if (forUserCName != null) {
-                    List<String> names = (List<String>)options.get(Option.ALLOW_S4U2SELF);
+                    List<String> names = (List<String>)
+                            options.get(Option.ALLOW_S4U2SELF);
                     if (!names.contains(cname.toString())) {
                         // Mimic the normal KDC behavior. When a server is not
                         // allowed to send S4U2self, do not send an error.
@@ -732,11 +877,19 @@
             EncryptionKey key = generateRandomKey(e2);
 
             // Check time, TODO
+            KerberosTime from = body.from;
             KerberosTime till = body.till;
+            if (from == null || from.isZero()) {
+                from = timeAfter(0);
+            }
+            KerberosTime rtime = body.rtime;
             if (till == null) {
                 throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
             } else if (till.isZero()) {
-                till = new KerberosTime(new Date().getTime() + 1000 * 3600 * 11);
+                till = timeAfter(DEFAULT_LIFETIME);
+            }
+            if (rtime == null && body.kdcOptions.get(KDCOptions.RENEWABLE)) {
+                rtime = timeAfter(DEFAULT_RENEWTIME);
             }
 
             boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
@@ -750,13 +903,19 @@
                     bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
                 }
             }
+            // We do not request for addresses for FORWARDED tickets
+            if (options.containsKey(Option.CHECK_ADDRESSES)
+                    && body.kdcOptions.get(KDCOptions.FORWARDED)
+                    && body.addresses != null) {
+                throw new KrbException(Krb5.KDC_ERR_BADOPTION);
+            }
             if (body.kdcOptions.get(KDCOptions.FORWARDED) ||
                     etp.flags.get(Krb5.TKT_OPTS_FORWARDED)) {
                 bFlags[Krb5.TKT_OPTS_FORWARDED] = true;
             }
             if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
                 bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
-                //renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7);
+                //renew = timeAfter(3600 * 24 * 7);
             }
             if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
                 bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
@@ -767,7 +926,8 @@
             if (body.kdcOptions.get(KDCOptions.ALLOW_POSTDATE)) {
                 bFlags[Krb5.TKT_OPTS_MAY_POSTDATE] = true;
             }
-            if (body.kdcOptions.get(KDCOptions.CNAME_IN_ADDL_TKT)) {
+            if (body.kdcOptions.get(KDCOptions.CNAME_IN_ADDL_TKT) &&
+                    !isReferral) {
                 if (!options.containsKey(Option.ALLOW_S4U2PROXY)) {
                     // Don't understand CNAME_IN_ADDL_TKT
                     throw new KrbException(Krb5.KDC_ERR_BADOPTION);
@@ -775,7 +935,8 @@
                     Map<String,List<String>> map = (Map<String,List<String>>)
                             options.get(Option.ALLOW_S4U2PROXY);
                     Ticket second = KDCReqBodyDotFirstAdditionalTicket(body);
-                    EncryptionKey key2 = keyForUser(second.sname, second.encPart.getEType(), true);
+                    EncryptionKey key2 = keyForUser(
+                            second.sname, second.encPart.getEType(), true);
                     byte[] bb = second.encPart.decrypt(key2, KeyUsage.KU_TICKET);
                     DerInputStream derIn = new DerInputStream(bb);
                     DerValue der = derIn.getDerValue();
@@ -807,19 +968,29 @@
             }
             bFlags[Krb5.TKT_OPTS_INITIAL] = true;
 
+            KerberosTime renewTill = etp.renewTill;
+            if (renewTill != null && body.kdcOptions.get(KDCOptions.RENEW)) {
+                // till should never pass renewTill
+                if (till.greaterThan(renewTill)) {
+                    till = renewTill;
+                }
+                if (System.getProperty("test.set.null.renew") != null) {
+                    // Testing 8186576, see NullRenewUntil.java.
+                    renewTill = null;
+                }
+            }
+
             TicketFlags tFlags = new TicketFlags(bFlags);
             EncTicketPart enc = new EncTicketPart(
                     tFlags,
                     key,
                     cname,
                     new TransitedEncoding(1, new byte[0]),  // TODO
-                    new KerberosTime(new Date()),
-                    body.from,
-                    till, body.rtime,
-                    body.addresses != null  // always set caddr
-                            ? body.addresses
-                            : new HostAddresses(
-                                new InetAddress[]{InetAddress.getLocalHost()}),
+                    timeAfter(0),
+                    from,
+                    till, renewTill,
+                    body.addresses != null ? body.addresses
+                            : etp.caddr,
                     null);
             EncryptionKey skey = keyForUser(service, e3, true);
             if (skey == null) {
@@ -833,23 +1004,22 @@
             );
             EncTGSRepPart enc_part = new EncTGSRepPart(
                     key,
-                    new LastReq(new LastReqEntry[]{
-                        new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000))
+                    new LastReq(new LastReqEntry[] {
+                        new LastReqEntry(0, timeAfter(-10))
                     }),
                     body.getNonce(),    // TODO: detect replay
-                    new KerberosTime(new Date().getTime() + 1000 * 3600 * 24),
+                    timeAfter(3600 * 24),
                     // Next 5 and last MUST be same with ticket
                     tFlags,
-                    new KerberosTime(new Date()),
-                    body.from,
-                    till, body.rtime,
+                    timeAfter(0),
+                    from,
+                    till, renewTill,
                     service,
-                    body.addresses != null  // always set caddr
-                            ? body.addresses
-                            : new HostAddresses(
-                                new InetAddress[]{InetAddress.getLocalHost()})
+                    body.addresses,
+                    null
                     );
-            EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
+            EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(),
+                    KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
             TGSRep tgsRep = new TGSRep(null,
                     cname,
                     t,
@@ -870,7 +1040,7 @@
                     + " " +ke.returnCodeMessage());
             if (kerr == null) {
                 kerr = new KRBError(null, null, null,
-                        new KerberosTime(new Date()),
+                        timeAfter(0),
                         0,
                         ke.returnCode(),
                         body.cname,
@@ -890,6 +1060,7 @@
      */
     protected byte[] processAsReq(byte[] in) throws Exception {
         ASReq asReq = new ASReq(in);
+        byte[] asReqbytes = asReq.asn1Encode();
         int[] eTypes = null;
         List<PAData> outPAs = new ArrayList<>();
 
@@ -906,9 +1077,29 @@
 
             KDCReqBody body = asReq.reqBody;
 
-            eTypes = KDCReqBodyDotEType(body);
+            eTypes = filterSupported(KDCReqBodyDotEType(body));
+            if (eTypes.length == 0) {
+                throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
+            }
             int eType = eTypes[0];
 
+            if (body.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+                PrincipalName principal = alias2Principals.get(
+                        body.cname.getNameString());
+                if (principal != null) {
+                    body.cname = principal;
+                } else {
+                    KDC referral = aliasReferrals.get(body.cname.getNameString());
+                    if (referral != null) {
+                        body.cname = new PrincipalName(
+                                PrincipalName.TGS_DEFAULT_SRV_NAME,
+                                PrincipalName.KRB_NT_SRV_INST,
+                                referral.getRealm());
+                        throw new KrbException(Krb5.KRB_ERR_WRONG_REALM);
+                    }
+                }
+            }
+
             EncryptionKey ckey = keyForUser(body.cname, eType, false);
             EncryptionKey skey = keyForUser(service, eType, true);
 
@@ -936,8 +1127,12 @@
             // Session key
             EncryptionKey key = generateRandomKey(eType);
             // Check time, TODO
+            KerberosTime from = body.from;
             KerberosTime till = body.till;
             KerberosTime rtime = body.rtime;
+            if (from == null || from.isZero()) {
+                from = timeAfter(0);
+            }
             if (till == null) {
                 throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
             } else if (till.isZero()) {
@@ -963,7 +1158,8 @@
             if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) {
                 List<String> sensitives = (List<String>)
                         options.get(Option.SENSITIVE_ACCOUNTS);
-                if (sensitives != null && sensitives.contains(body.cname.toString())) {
+                if (sensitives != null
+                        && sensitives.contains(body.cname.toString())) {
                     // Cannot make FORWARDABLE
                 } else {
                     bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
@@ -971,7 +1167,7 @@
             }
             if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
                 bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
-                //renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7);
+                //renew = timeAfter(3600 * 24 * 7);
             }
             if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
                 bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
@@ -993,7 +1189,8 @@
                         pas2 = new DerValue[] {
                             new DerValue(new ETypeInfo2(1, null, null).asn1Encode()),
                             new DerValue(new ETypeInfo2(1, "", null).asn1Encode()),
-                            new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()),
+                            new DerValue(new ETypeInfo2(
+                                    1, realm, new byte[]{1}).asn1Encode()),
                         };
                         pas = new DerValue[] {
                             new DerValue(new ETypeInfo(1, null).asn1Encode()),
@@ -1003,7 +1200,8 @@
                         break;
                     case 2:     // we still reject non-null s2kparams and prefer E2 over E
                         pas2 = new DerValue[] {
-                            new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()),
+                            new DerValue(new ETypeInfo2(
+                                    1, realm, new byte[]{1}).asn1Encode()),
                             new DerValue(new ETypeInfo2(1, null, null).asn1Encode()),
                             new DerValue(new ETypeInfo2(1, "", null).asn1Encode()),
                         };
@@ -1054,7 +1252,7 @@
                             epas[i],
                             epas[i] == EncryptedData.ETYPE_ARCFOUR_HMAC ?
                                 null : getSalt(body.cname),
-                            null).asn1Encode());
+                            getParams(body.cname, epas[i])).asn1Encode());
                 }
                 boolean allOld = true;
                 for (int i: eTypes) {
@@ -1088,21 +1286,47 @@
                 outPAs.add(new PAData(Krb5.PA_ETYPE_INFO, eid.toByteArray()));
             }
 
-            PAData[] inPAs = KDCReqDotPAData(asReq);
-            if (inPAs == null || inPAs.length == 0) {
+            PAData[] inPAs = asReq.pAData;
+            List<PAData> enc_outPAs = new ArrayList<>();
+
+            byte[] paEncTimestamp = null;
+            if (inPAs != null) {
+                for (PAData inPA : inPAs) {
+                    if (inPA.getType() == Krb5.PA_ENC_TIMESTAMP) {
+                        paEncTimestamp = inPA.getValue();
+                    }
+                }
+            }
+
+            if (paEncTimestamp == null) {
                 Object preauth = options.get(Option.PREAUTH_REQUIRED);
                 if (preauth == null || preauth.equals(Boolean.TRUE)) {
                     throw new KrbException(Krb5.KDC_ERR_PREAUTH_REQUIRED);
                 }
             } else {
+                EncryptionKey pakey = null;
                 try {
-                    EncryptedData data = newEncryptedData(new DerValue(inPAs[0].getValue()));
-                    EncryptionKey pakey = keyForUser(body.cname, data.getEType(), false);
+                    EncryptedData data = newEncryptedData(
+                            new DerValue(paEncTimestamp));
+                    pakey = keyForUser(body.cname, data.getEType(), false);
                     data.decrypt(pakey, KeyUsage.KU_PA_ENC_TS);
                 } catch (Exception e) {
-                    throw new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED);
+                    KrbException ke = new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED);
+                    ke.initCause(e);
+                    throw ke;
                 }
                 bFlags[Krb5.TKT_OPTS_PRE_AUTHENT] = true;
+                for (PAData pa : inPAs) {
+                    if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+                        Checksum ckSum = new Checksum(
+                                Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128,
+                                asReqbytes, ckey, KeyUsage.KU_AS_REQ);
+                        enc_outPAs.add(new PAData(Krb5.PA_REQ_ENC_PA_REP,
+                                ckSum.asn1Encode()));
+                        bFlags[Krb5.TKT_OPTS_ENC_PA_REP] = true;
+                        break;
+                    }
+                }
             }
 
             TicketFlags tFlags = new TicketFlags(bFlags);
@@ -1111,8 +1335,8 @@
                     key,
                     body.cname,
                     new TransitedEncoding(1, new byte[0]),
-                    new KerberosTime(new Date()),
-                    body.from,
+                    timeAfter(0),
+                    from,
                     till, rtime,
                     body.addresses,
                     null);
@@ -1123,19 +1347,21 @@
             EncASRepPart enc_part = new EncASRepPart(
                     key,
                     new LastReq(new LastReqEntry[]{
-                        new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000))
+                        new LastReqEntry(0, timeAfter(-10))
                     }),
                     body.getNonce(),    // TODO: detect replay?
-                    new KerberosTime(new Date().getTime() + 1000 * 3600 * 24),
+                    timeAfter(3600 * 24),
                     // Next 5 and last MUST be same with ticket
                     tFlags,
-                    new KerberosTime(new Date()),
-                    body.from,
+                    timeAfter(0),
+                    from,
                     till, rtime,
                     service,
-                    body.addresses
+                    body.addresses,
+                    enc_outPAs.toArray(new PAData[enc_outPAs.size()])
                     );
-            EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_AS_REP_PART);
+            EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(),
+                    KeyUsage.KU_ENC_AS_REP_PART);
             ASRep asRep = new ASRep(
                     outPAs.toArray(new PAData[outPAs.size()]),
                     body.cname,
@@ -1180,8 +1406,10 @@
             if (kerr == null) {
                 if (ke.returnCode() == Krb5.KDC_ERR_PREAUTH_REQUIRED ||
                         ke.returnCode() == Krb5.KDC_ERR_PREAUTH_FAILED) {
+                    outPAs.add(new PAData(Krb5.PA_ENC_TIMESTAMP, new byte[0]));
+                }
+                if (outPAs.size() > 0) {
                     DerOutputStream bytes = new DerOutputStream();
-                    bytes.write(new PAData(Krb5.PA_ENC_TIMESTAMP, new byte[0]).asn1Encode());
                     for (PAData p: outPAs) {
                         bytes.write(p.asn1Encode());
                     }
@@ -1190,7 +1418,7 @@
                     eData = temp.toByteArray();
                 }
                 kerr = new KRBError(null, null, null,
-                        new KerberosTime(new Date()),
+                        timeAfter(0),
                         0,
                         ke.returnCode(),
                         body.cname,
@@ -1268,6 +1496,35 @@
         throw new KrbException("Illegal duration format " + s);
     }
 
+    private int[] filterSupported(int[] input) {
+        int count = 0;
+        for (int i = 0; i < input.length; i++) {
+            if (!EType.isSupported(input[i])) {
+                continue;
+            }
+            if (SUPPORTED_ETYPES != null) {
+                boolean supported = false;
+                for (String se : SUPPORTED_ETYPES.split(",")) {
+                    if (Config.getType(se) == input[i]) {
+                        supported = true;
+                        break;
+                    }
+                }
+                if (!supported) {
+                    continue;
+                }
+            }
+            if (count != i) {
+                input[count] = input[i];
+            }
+            count++;
+        }
+        if (count != input.length) {
+            input = Arrays.copyOf(input, count);
+        }
+        return input;
+    }
+
     /**
      * Generates a line for a KDC to put inside [realms] of krb5.conf
      * @return REALM.NAME = { kdc = host:port etc }
@@ -1292,6 +1549,20 @@
      * @throws java.io.IOException for any communication error
      */
     protected void startServer(int port, boolean asDaemon) throws IOException {
+        if (nativeKdc != null) {
+            startNativeServer(port, asDaemon);
+        } else {
+            startJavaServer(port, asDaemon);
+        }
+    }
+
+    private void startNativeServer(int port, boolean asDaemon) throws IOException {
+        nativeKdc.prepare();
+        nativeKdc.init();
+        kdcProc = nativeKdc.kdc();
+    }
+
+    private void startJavaServer(int port, boolean asDaemon) throws IOException {
         if (port > 0) {
             u1 = new DatagramSocket(port, InetAddress.getByName("127.0.0.1"));
             t1 = new ServerSocket(port);
@@ -1384,19 +1655,37 @@
         }
     }
 
+    public void kinit(String user, String ccache) throws Exception {
+        if (user.indexOf('@') < 0) {
+            user = user + "@" + realm;
+        }
+        if (nativeKdc != null) {
+            nativeKdc.kinit(user, ccache);
+        } else {
+            Context.fromUserPass(user, passwords.get(user), false)
+                    .ccache(ccache);
+        }
+    }
+
     boolean isReady() {
         return udpConsumerReady && tcpConsumerReady && dispatcherReady;
     }
 
     public void terminate() {
-        try {
-            thread1.stop();
-            thread2.stop();
-            thread3.stop();
-            u1.close();
-            t1.close();
-        } catch (Exception e) {
-            // OK
+        if (nativeKdc != null) {
+            System.out.println("Killing kdc...");
+            kdcProc.destroyForcibly();
+            System.out.println("Done");
+        } else {
+            try {
+                thread1.stop();
+                thread2.stop();
+                thread3.stop();
+                u1.close();
+                t1.close();
+            } catch (Exception e) {
+                // OK
+            }
         }
     }
 
@@ -1551,8 +1840,270 @@
         }
     }
 
+    /**
+     * A native KDC using the binaries in nativePath. Attention:
+     * this is using binaries, not an existing KDC instance.
+     * An implementation of this takes care of configuration,
+     * principal db managing and KDC startup.
+     */
+    static abstract class NativeKdc {
+
+        protected Map<String,String> env;
+        protected String nativePath;
+        protected String base;
+        protected String realm;
+        protected int port;
+
+        NativeKdc(String nativePath, KDC kdc) {
+            if (kdc.port == 0) {
+                kdc.port = 8000 + new java.util.Random().nextInt(10000);
+            }
+            this.nativePath = nativePath;
+            this.realm = kdc.realm;
+            this.port = kdc.port;
+            this.base = Paths.get("" + port).toAbsolutePath().toString();
+        }
+
+        // Add a new principal
+        abstract void addPrincipal(String user, String pass);
+        // Add a keytab entry
+        abstract void ktadd(String user, String ktab);
+        // Initialize KDC
+        abstract void init();
+        // Start kdc
+        abstract Process kdc();
+        // Configuration
+        abstract void prepare();
+        // Fill ccache
+        abstract void kinit(String user, String ccache);
+
+        static NativeKdc get(KDC kdc) {
+            String prop = System.getProperty("native.kdc.path");
+            if (prop == null) {
+                return null;
+            } else if (Files.exists(Paths.get(prop, "sbin/krb5kdc"))) {
+                return new MIT(true, prop, kdc);
+            } else if (Files.exists(Paths.get(prop, "kdc/krb5kdc"))) {
+                return new MIT(false, prop, kdc);
+            } else if (Files.exists(Paths.get(prop, "libexec/kdc"))) {
+                return new Heimdal(prop, kdc);
+            } else {
+                throw new IllegalArgumentException("Strange " + prop);
+            }
+        }
+
+        Process run(boolean wait, String... cmd) {
+            try {
+                System.out.println("Running " + cmd2str(env, cmd));
+                ProcessBuilder pb = new ProcessBuilder();
+                pb.inheritIO();
+                pb.environment().putAll(env);
+                Process p = pb.command(cmd).start();
+                if (wait) {
+                    if (p.waitFor() < 0) {
+                        throw new RuntimeException("exit code is not null");
+                    }
+                    return null;
+                } else {
+                    return p;
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        private String cmd2str(Map<String,String> env, String... cmd) {
+            return env.entrySet().stream().map(e -> e.getKey()+"="+e.getValue())
+                    .collect(Collectors.joining(" ")) + " " +
+                    Stream.of(cmd).collect(Collectors.joining(" "));
+        }
+    }
+
+    // Heimdal KDC. Build your own and run "make install" to nativePath.
+    static class Heimdal extends NativeKdc {
+
+        Heimdal(String nativePath, KDC kdc) {
+            super(nativePath, kdc);
+            Map<String, String> environment = new HashMap<>();
+            environment.put("KRB5_CONFIG", base + "/krb5.conf");
+            environment.put("KRB5_TRACE", "/dev/stderr");
+            environment.put("DYLD_LIBRARY_PATH", nativePath + "/lib");
+            environment.put("LD_LIBRARY_PATH", nativePath + "/lib");
+            this.env = Collections.unmodifiableMap(environment);
+        }
+
+        @Override
+        public void addPrincipal(String user, String pass) {
+            run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
+                    "add", "-p", pass, "--use-defaults", user);
+        }
+
+        @Override
+        public void ktadd(String user, String ktab) {
+            run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
+                    "ext_keytab", "-k", ktab, user);
+        }
+
+        @Override
+        public void init() {
+            run(true, nativePath + "/bin/kadmin",  "-l",  "-r", realm,
+                    "init", "--realm-max-ticket-life=1day",
+                    "--realm-max-renewable-life=1month", realm);
+        }
+
+        @Override
+        public Process kdc() {
+            return run(false, nativePath + "/libexec/kdc",
+                    "--addresses=127.0.0.1", "-P", "" + port);
+        }
+
+        @Override
+        public void prepare() {
+            try {
+                Files.createDirectory(Paths.get(base));
+                Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList(
+                        "[libdefaults]",
+                        "default_realm = " + realm,
+                        "default_keytab_name = FILE:" + base + "/krb5.keytab",
+                        "forwardable = true",
+                        "dns_lookup_kdc = no",
+                        "dns_lookup_realm = no",
+                        "dns_canonicalize_hostname = false",
+                        "\n[realms]",
+                        realm + " = {",
+                        "  kdc = localhost:" + port,
+                        "}",
+                        "\n[kdc]",
+                        "db-dir = " + base,
+                        "database = {",
+                        "    label = {",
+                        "        dbname = " + base + "/current-db",
+                        "        realm = " + realm,
+                        "        mkey_file = " + base + "/mkey.file",
+                        "        acl_file = " + base + "/heimdal.acl",
+                        "        log_file = " + base + "/current.log",
+                        "    }",
+                        "}",
+                        SUPPORTED_ETYPES == null ? ""
+                                : ("\n[kadmin]\ndefault_keys = "
+                                + (SUPPORTED_ETYPES + ",")
+                                        .replaceAll(",", ":pw-salt ")),
+                        "\n[logging]",
+                        "kdc = 0-/FILE:" + base + "/messages.log",
+                        "krb5 = 0-/FILE:" + base + "/messages.log",
+                        "default = 0-/FILE:" + base + "/messages.log"
+                ));
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+        }
+
+        @Override
+        void kinit(String user, String ccache) {
+            String tmpName = base + "/" + user + "." +
+                    System.identityHashCode(this) + ".keytab";
+            ktadd(user, tmpName);
+            run(true, nativePath + "/bin/kinit",
+                    "-f", "-t", tmpName, "-c", ccache, user);
+        }
+    }
+
+    // MIT krb5 KDC. Make your own exploded (install == false), or
+    // "make install" into nativePath (install == true).
+    static class MIT extends NativeKdc {
+
+        private boolean install; // "make install" or "make"
+
+        MIT(boolean install, String nativePath, KDC kdc) {
+            super(nativePath, kdc);
+            this.install = install;
+            Map<String, String> environment = new HashMap<>();
+            environment.put("KRB5_KDC_PROFILE", base + "/kdc.conf");
+            environment.put("KRB5_CONFIG", base + "/krb5.conf");
+            environment.put("KRB5_TRACE", "/dev/stderr");
+            environment.put("DYLD_LIBRARY_PATH", nativePath + "/lib");
+            environment.put("LD_LIBRARY_PATH", nativePath + "/lib");
+            this.env = Collections.unmodifiableMap(environment);
+        }
+
+        @Override
+        public void addPrincipal(String user, String pass) {
+            run(true, nativePath +
+                    (install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local",
+                    "-q", "addprinc -pw " + pass + " " + user);
+        }
+
+        @Override
+        public void ktadd(String user, String ktab) {
+            run(true, nativePath +
+                    (install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local",
+                    "-q", "ktadd -k " + ktab + " -norandkey " + user);
+        }
+
+        @Override
+        public void init() {
+            run(true, nativePath +
+                    (install ? "/sbin/" : "/kadmin/dbutil/") + "kdb5_util",
+                    "create", "-s", "-W", "-P", "olala");
+        }
+
+        @Override
+        public Process kdc() {
+            return run(false, nativePath +
+                    (install ? "/sbin/" : "/kdc/") + "krb5kdc",
+                    "-n");
+        }
+
+        @Override
+        public void prepare() {
+            try {
+                Files.createDirectory(Paths.get(base));
+                Files.write(Paths.get(base + "/kdc.conf"), Arrays.asList(
+                        "[kdcdefaults]",
+                        "\n[realms]",
+                        realm + "= {",
+                        "  kdc_listen = " + this.port,
+                        "  kdc_tcp_listen = " + this.port,
+                        "  database_name = " + base + "/principal",
+                        "  key_stash_file = " + base + "/.k5.ATHENA.MIT.EDU",
+                        SUPPORTED_ETYPES == null ? ""
+                                : ("  supported_enctypes = "
+                                + (SUPPORTED_ETYPES + ",")
+                                        .replaceAll(",", ":normal ")),
+                        "}"
+                ));
+                Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList(
+                        "[libdefaults]",
+                        "default_realm = " + realm,
+                        "default_keytab_name = FILE:" + base + "/krb5.keytab",
+                        "forwardable = true",
+                        "dns_lookup_kdc = no",
+                        "dns_lookup_realm = no",
+                        "dns_canonicalize_hostname = false",
+                        "\n[realms]",
+                        realm + " = {",
+                        "  kdc = localhost:" + port,
+                        "}",
+                        "\n[logging]",
+                        "kdc = FILE:" + base + "/krb5kdc.log"
+                ));
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+        }
+
+        @Override
+        void kinit(String user, String ccache) {
+            String tmpName = base + "/" + user + "." +
+                    System.identityHashCode(this) + ".keytab";
+            ktadd(user, tmpName);
+            run(true, nativePath +
+                    (install ? "/bin/" : "/clients/kinit/") + "kinit",
+                    "-f", "-t", tmpName, "-c", ccache, user);
+        }
+    }
+
     // Calling private methods thru reflections
-    private static final Field getPADataField;
     private static final Field getEType;
     private static final Constructor<EncryptedData> ctorEncryptedData;
     private static final Method stringToKey;
@@ -1562,8 +2113,6 @@
         try {
             ctorEncryptedData = EncryptedData.class.getDeclaredConstructor(DerValue.class);
             ctorEncryptedData.setAccessible(true);
-            getPADataField = KDCReq.class.getDeclaredField("pAData");
-            getPADataField.setAccessible(true);
             getEType = KDCReqBody.class.getDeclaredField("eType");
             getEType.setAccessible(true);
             stringToKey = EncryptionKey.class.getDeclaredMethod(
@@ -1585,13 +2134,6 @@
             throw new AssertionError(e);
         }
     }
-    private static PAData[] KDCReqDotPAData(KDCReq req) {
-        try {
-            return (PAData[])getPADataField.get(req);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
     private static int[] KDCReqBodyDotEType(KDCReqBody body) {
         try {
             return (int[]) getEType.get(body);
diff --git a/test/sun/security/krb5/auto/LifeTimeInSeconds.java b/test/sun/security/krb5/auto/LifeTimeInSeconds.java
index 9d4c6d7..23c95318 100644
--- a/test/sun/security/krb5/auto/LifeTimeInSeconds.java
+++ b/test/sun/security/krb5/auto/LifeTimeInSeconds.java
@@ -40,7 +40,7 @@
         int time = cred.getRemainingLifetime();
         int time2 = cred.getRemainingInitLifetime(null);
         // The test KDC issues a TGT with a default lifetime of 11 hours
-        int elevenhrs = 11*3600;
+        int elevenhrs = KDC.DEFAULT_LIFETIME;
         if (time > elevenhrs+60 || time < elevenhrs-60) {
             throw new Exception("getRemainingLifetime returns wrong value.");
         }
diff --git a/test/sun/security/krb5/auto/NullRenewUntil.java b/test/sun/security/krb5/auto/NullRenewUntil.java
new file mode 100644
index 0000000..2f7d4a4
--- /dev/null
+++ b/test/sun/security/krb5/auto/NullRenewUntil.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 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 8186576
+ * @summary KerberosTicket does not properly handle renewable tickets
+ *          at the end of their lifetime
+ * @library /lib/testlibrary/
+ * @compile -XDignore.symbol.file NullRenewUntil.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock -Dtest.set.null.renew NullRenewUntil
+ */
+
+import jdk.testlibrary.Asserts;
+import sun.security.krb5.Config;
+
+import javax.security.auth.kerberos.KerberosTicket;
+
+public class NullRenewUntil {
+
+    public static void main(String[] args) throws Exception {
+
+        OneKDC kdc = new OneKDC(null);
+
+        KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+                "ticket_lifetime = 10s",
+                "renew_lifetime = 11s");
+        Config.refresh();
+
+        KerberosTicket ticket = Context
+                .fromUserPass(OneKDC.USER, OneKDC.PASS, false).s()
+                .getPrivateCredentials(KerberosTicket.class).iterator().next();
+
+        System.out.println(ticket);
+        Asserts.assertTrue(ticket.getRenewTill() != null, ticket.toString());
+
+        Thread.sleep(2000);
+
+        ticket.refresh();
+        System.out.println(ticket);
+        Asserts.assertTrue(ticket.getRenewTill() == null, ticket.toString());
+
+        Thread.sleep(2000);
+        ticket.refresh();
+        System.out.println(ticket);
+    }
+}
diff --git a/test/sun/security/krb5/auto/ReferralsTest.java b/test/sun/security/krb5/auto/ReferralsTest.java
new file mode 100644
index 0000000..32e5634
--- /dev/null
+++ b/test/sun/security/krb5/auto/ReferralsTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc.
+ * 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 8215032
+ * @run main/othervm/timeout=120 -Dsun.security.krb5.debug=true ReferralsTest
+ * @summary Test Kerberos cross-realm referrals (RFC 6806)
+ */
+
+import java.io.File;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.Subject;
+
+import org.ietf.jgss.GSSName;
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.PrincipalName;
+
+public class ReferralsTest {
+    private static final boolean DEBUG = true;
+    private static final String krbConfigName = "krb5-localkdc.conf";
+    private static final String realmKDC1 = "RABBIT.HOLE";
+    private static final String realmKDC2 = "DEV.RABBIT.HOLE";
+    private static final char[] password = "123qwe@Z".toCharArray();
+
+    // Names
+    private static final String clientName = "test";
+    private static final String serviceName = "http" +
+            PrincipalName.NAME_COMPONENT_SEPARATOR_STR +
+            "server.dev.rabbit.hole";
+
+    // Alias
+    private static final String clientAlias = clientName +
+            PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1;
+
+    // Names + realms
+    private static final String clientKDC1Name = clientAlias.replaceAll(
+            PrincipalName.NAME_REALM_SEPARATOR_STR, "\\\\" +
+            PrincipalName.NAME_REALM_SEPARATOR_STR) +
+            PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1;
+    private static final String clientKDC2Name = clientName +
+            PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2;
+    private static final String serviceKDC2Name = serviceName +
+            PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            initializeKDCs();
+            testSubjectCredentials();
+            testDelegated();
+        } finally {
+            cleanup();
+        }
+    }
+
+    private static void initializeKDCs() throws Exception {
+        KDC kdc1 = KDC.create(realmKDC1, "localhost", 0, true);
+        kdc1.addPrincipalRandKey(PrincipalName.TGS_DEFAULT_SRV_NAME +
+                PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1);
+        kdc1.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME +
+                PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1 +
+                PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2,
+                password);
+        kdc1.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME +
+                PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2,
+                password);
+
+        KDC kdc2 = KDC.create(realmKDC2, "localhost", 0, true);
+        kdc2.addPrincipalRandKey(PrincipalName.TGS_DEFAULT_SRV_NAME +
+                PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2);
+        kdc2.addPrincipal(clientKDC2Name, password);
+        kdc2.addPrincipal(serviceName, password);
+        kdc2.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME +
+                PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1,
+                password);
+        kdc2.addPrincipal(PrincipalName.TGS_DEFAULT_SRV_NAME +
+                PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2 +
+                PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1,
+                password);
+
+        kdc1.registerAlias(clientAlias, kdc2);
+        kdc1.registerAlias(serviceName, kdc2);
+        kdc2.registerAlias(clientAlias, clientKDC2Name);
+
+        Map<String,List<String>> mapKDC2 = new HashMap<>();
+        mapKDC2.put(serviceName + "@" + realmKDC2, Arrays.asList(
+                new String[]{serviceName + "@" + realmKDC2}));
+        kdc2.setOption(KDC.Option.ALLOW_S4U2PROXY, mapKDC2);
+
+        KDC.saveConfig(krbConfigName, kdc1, kdc2,
+                    "forwardable=true");
+        System.setProperty("java.security.krb5.conf", krbConfigName);
+    }
+
+    private static void cleanup() {
+        File f = new File(krbConfigName);
+        if (f.exists()) {
+            f.delete();
+        }
+    }
+
+    /*
+     * The client subject (whose principal is
+     * test@RABBIT.HOLE@RABBIT.HOLE) will obtain a TGT after
+     * realm referral and name canonicalization (TGT cname
+     * will be test@DEV.RABBIT.HOLE). With this TGT, the client will request
+     * a TGS for service http/server.dev.rabbit.hole@RABBIT.HOLE. After
+     * realm referral, a http/server.dev.rabbit.hole@DEV.RABBIT.HOLE TGS
+     * will be obtained.
+     *
+     * Assert that we get the proper TGT and TGS tickets, and that they are
+     * associated to the client subject.
+     *
+     * Assert that if we request a TGS for the same service again (based on the
+     * original service name), we don't get a new one but the previous,
+     * already in the subject credentials.
+     */
+    private static void testSubjectCredentials() throws Exception {
+        Subject clientSubject = new Subject();
+        Context clientContext = Context.fromUserPass(clientSubject,
+                clientKDC1Name, password, false);
+
+        Set<Principal> clientPrincipals = clientSubject.getPrincipals();
+        if (clientPrincipals.size() != 1) {
+            throw new Exception("Only one client subject principal expected");
+        }
+        Principal clientPrincipal = clientPrincipals.iterator().next();
+        if (DEBUG) {
+            System.out.println("Client subject principal: " +
+                    clientPrincipal.getName());
+        }
+        if (!clientPrincipal.getName().equals(clientKDC1Name)) {
+            throw new Exception("Unexpected client subject principal.");
+        }
+
+        clientContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+        clientContext.take(new byte[0]);
+        Set<KerberosTicket> clientTickets =
+                clientSubject.getPrivateCredentials(KerberosTicket.class);
+        boolean tgtFound = false;
+        boolean tgsFound = false;
+        for (KerberosTicket clientTicket : clientTickets) {
+            String cname = clientTicket.getClient().getName();
+            String sname = clientTicket.getServer().getName();
+            if (cname.equals(clientKDC2Name)) {
+                if (sname.equals(PrincipalName.TGS_DEFAULT_SRV_NAME +
+                        PrincipalName.NAME_COMPONENT_SEPARATOR_STR +
+                        realmKDC2 + PrincipalName.NAME_REALM_SEPARATOR_STR +
+                        realmKDC2)) {
+                    tgtFound = true;
+                } else if (sname.equals(serviceKDC2Name)) {
+                    tgsFound = true;
+                }
+            }
+            if (DEBUG) {
+                System.out.println("Client subject KerberosTicket:");
+                System.out.println(clientTicket);
+            }
+        }
+        if (!tgtFound || !tgsFound) {
+            throw new Exception("client subject tickets (TGT/TGS) not found.");
+        }
+        int numOfTickets = clientTickets.size();
+        clientContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+        clientContext.take(new byte[0]);
+        clientContext.status();
+        int newNumOfTickets =
+                clientSubject.getPrivateCredentials(KerberosTicket.class).size();
+        if (DEBUG) {
+            System.out.println("client subject number of tickets: " +
+                    numOfTickets);
+            System.out.println("client subject new number of tickets: " +
+                    newNumOfTickets);
+        }
+        if (numOfTickets != newNumOfTickets) {
+            throw new Exception("Useless client subject TGS request because" +
+                    " TGS was not found in private credentials.");
+        }
+    }
+
+    /*
+     * The server (http/server.dev.rabbit.hole@DEV.RABBIT.HOLE)
+     * will authenticate on itself on behalf of the client
+     * (test@DEV.RABBIT.HOLE). Cross-realm referrals will occur
+     * when requesting different TGTs and TGSs (including the
+     * request for delegated credentials).
+     */
+    private static void testDelegated() throws Exception {
+        Context c = Context.fromUserPass(clientKDC2Name,
+                password, false);
+        c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+        Context s = Context.fromUserPass(serviceKDC2Name,
+                password, true);
+        s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+        Context.handshake(c, s);
+        Context delegatedContext = s.delegated();
+        delegatedContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+        delegatedContext.x().requestMutualAuth(false);
+        Context s2 = Context.fromUserPass(serviceKDC2Name,
+                password, true);
+        s2.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+        // Test authentication
+        Context.handshake(delegatedContext, s2);
+        if (!delegatedContext.x().isEstablished() || !s2.x().isEstablished()) {
+            throw new Exception("Delegated authentication failed");
+        }
+
+        // Test identities
+        GSSName contextInitiatorName = delegatedContext.x().getSrcName();
+        GSSName contextAcceptorName = delegatedContext.x().getTargName();
+        if (DEBUG) {
+            System.out.println("Context initiator: " + contextInitiatorName);
+            System.out.println("Context acceptor: " + contextAcceptorName);
+        }
+        if (!contextInitiatorName.toString().equals(clientKDC2Name) ||
+                !contextAcceptorName.toString().equals(serviceName)) {
+            throw new Exception("Unexpected initiator or acceptor names");
+        }
+    }
+}
diff --git a/test/sun/security/krb5/auto/Renew.java b/test/sun/security/krb5/auto/Renew.java
new file mode 100644
index 0000000..fdfb488
--- /dev/null
+++ b/test/sun/security/krb5/auto/Renew.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 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 8058290
+ * @summary JAAS Krb5LoginModule has suspect ticket-renewal logic,
+ *          relies on clockskew grace
+ * @compile -XDignore.symbol.file Renew.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 1
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 2
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 3
+ */
+
+import sun.security.krb5.Config;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Date;
+import javax.security.auth.kerberos.KerberosTicket;
+
+public class Renew {
+
+    public static void main(String[] args) throws Exception {
+
+        // Three test cases:
+        // 1. renewTGT=false
+        // 2. renewTGT=true with a short life time, renew will happen
+        // 3. renewTGT=true with a long life time, renew won't happen
+        int test = Integer.parseInt(args[0]);
+
+        OneKDC k = new OneKDC(null);
+        KDC.saveConfig(OneKDC.KRB5_CONF, k,
+                "renew_lifetime = 1d",
+                "ticket_lifetime = " + (test == 2? "10s": "8h"));
+        Config.refresh();
+        k.writeJAASConf();
+
+        // KDC would save ccache in a file
+        System.setProperty("test.kdc.save.ccache", "cache.here");
+
+        Files.write(Paths.get(OneKDC.JAAS_CONF), Arrays.asList(
+                "first {",
+                "   com.sun.security.auth.module.Krb5LoginModule required;",
+                "};",
+                "second {",
+                "   com.sun.security.auth.module.Krb5LoginModule required",
+                "   doNotPrompt=true",
+                "   renewTGT=" + (test != 1),
+                "   useTicketCache=true",
+                "   ticketCache=cache.here;",
+                "};"
+        ));
+
+        Context c;
+
+        // The first login uses username and password
+        c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+        Date d1 = c.s().getPrivateCredentials(KerberosTicket.class).iterator().next().getAuthTime();
+
+        // 6s is longer than half of 10s
+        Thread.sleep(6000);
+
+        // The second login uses the cache
+        c = Context.fromJAAS("second");
+        Date d2 = c.s().getPrivateCredentials(KerberosTicket.class).iterator().next().getAuthTime();
+
+        if (test == 2) {
+            if (d1.equals(d2)) {
+                throw new Exception("Ticket not renewed");
+            }
+        } else {
+            if (!d1.equals(d2)) {
+                throw new Exception("Ticket renewed");
+            }
+        }
+    }
+}
diff --git a/test/sun/security/krb5/auto/Renewal.java b/test/sun/security/krb5/auto/Renewal.java
new file mode 100644
index 0000000..38639c7
--- /dev/null
+++ b/test/sun/security/krb5/auto/Renewal.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8044500
+ * @summary Add kinit options and krb5.conf flags that allow users to
+ *          obtain renewable tickets and specify ticket lifetimes
+ * @library ../../../../java/security/testlibrary/
+ * @compile -XDignore.symbol.file Renewal.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renewal
+ */
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+import sun.security.krb5.internal.ccache.Credentials;
+import sun.security.krb5.internal.ccache.FileCredentialsCache;
+
+import javax.security.auth.kerberos.KerberosTicket;
+import java.util.Date;
+import java.util.Random;
+import java.util.Set;
+
+// The basic krb5 test skeleton you can copy from
+public class Renewal {
+
+    static OneKDC kdc;
+    static String clazz = "sun.security.krb5.internal.tools.Kinit";
+
+    public static void main(String[] args) throws Exception {
+
+        kdc = new OneKDC(null);
+        kdc.writeJAASConf();
+        kdc.setOption(KDC.Option.PREAUTH_REQUIRED, false);
+
+        checkLogin(null, null, KDC.DEFAULT_LIFETIME, -1);
+        checkLogin("1h", null, 3600, -1);
+        checkLogin(null, "2d", KDC.DEFAULT_LIFETIME, 86400*2);
+        checkLogin("1h", "10h", 3600, 36000);
+        // When rtime is before till, use till as rtime
+        checkLogin("10h", "1h", 36000, 36000);
+
+        try {
+            Class.forName(clazz);
+        } catch (ClassNotFoundException cnfe) {
+            return;
+        }
+
+        checkKinit(null, null, null, null, KDC.DEFAULT_LIFETIME, -1);
+        checkKinit("1h", "10h", null, null, 3600, 36000);
+        checkKinit(null, null, "30m", "5h", 1800, 18000);
+        checkKinit("1h", "10h", "30m", "5h", 1800, 18000);
+
+        checkKinitRenew();
+    }
+
+    static int count = 0;
+
+    static void checkKinit(
+            String s1,      // ticket_lifetime in krb5.conf, null if none
+            String s2,      // renew_lifetime in krb5.conf, null if none
+            String c1,      // -l on kinit, null if none
+            String c2,      // -r on kinit, null if none
+            int t1, int t2  // expected lifetimes, -1 of unexpected
+                ) throws Exception {
+        KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+                s1 != null ? ("ticket_lifetime = " + s1) : "",
+                s2 != null ? ("renew_lifetime = " + s2) : "");
+        Proc p = Proc.create(clazz);
+        if (c1 != null) {
+            p.args("-l", c1);
+        }
+        if (c2 != null) {
+            p.args("-r", c2);
+        }
+        count++;
+        p.args(OneKDC.USER, new String(OneKDC.PASS))
+                .inheritIO()
+                .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
+                .prop("java.security.krb5.conf", OneKDC.KRB5_CONF)
+                .env("KRB5CCNAME", "ccache" + count)
+                .start();
+        if (p.waitFor() != 0) {
+            throw new Exception();
+        }
+        FileCredentialsCache fcc =
+                FileCredentialsCache.acquireInstance(null, "ccache" + count);
+        Credentials cred = fcc.getDefaultCreds();
+        checkRough(cred.getEndTime().toDate(), t1);
+        if (cred.getRenewTill() == null) {
+            checkRough(null, t2);
+        } else {
+            checkRough(cred.getRenewTill().toDate(), t2);
+        }
+    }
+
+    static void checkKinitRenew() throws Exception {
+        Proc p = Proc.create(clazz)
+                .args("-R")
+                .inheritIO()
+                .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
+                .prop("java.security.krb5.conf", OneKDC.KRB5_CONF)
+                .env("KRB5CCNAME", "ccache" + count)
+                .start();
+        if (p.waitFor() != 0) {
+            throw new Exception();
+        }
+    }
+
+    static void checkLogin(
+            String s1,      // ticket_lifetime in krb5.conf, null if none
+            String s2,      // renew_lifetime in krb5.conf, null if none
+            int t1, int t2  // expected lifetimes, -1 of unexpected
+                ) throws Exception {
+        KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+                s1 != null ? ("ticket_lifetime = " + s1) : "",
+                s2 != null ? ("renew_lifetime = " + s2) : "");
+        Config.refresh();
+
+        Context c;
+        c = Context.fromJAAS("client");
+
+        Set<KerberosTicket> tickets =
+                c.s().getPrivateCredentials(KerberosTicket.class);
+        if (tickets.size() != 1) {
+            throw new Exception();
+        }
+        KerberosTicket ticket = tickets.iterator().next();
+
+        checkRough(ticket.getEndTime(), t1);
+        checkRough(ticket.getRenewTill(), t2);
+    }
+
+    static void checkRough(Date t, int duration) throws Exception {
+        Date now = new Date();
+        if (t == null && duration == -1) {
+            return;
+        }
+        long change = (t.getTime() - System.currentTimeMillis()) / 1000;
+        if (change > duration + 20 || change < duration - 20) {
+            throw new Exception(t + " is not " + duration);
+        }
+    }
+}
diff --git a/test/sun/security/krb5/auto/SaslGSS.java b/test/sun/security/krb5/auto/SaslGSS.java
deleted file mode 100644
index d21cfeb..0000000
--- a/test/sun/security/krb5/auto/SaslGSS.java
+++ /dev/null
@@ -1,137 +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.
- */
-
-/*
- * @test
- * @bug 8012082 8019267
- * @summary SASL: auth-conf negotiated, but unencrypted data is accepted,
-  *         reset to unencrypt
- * @compile -XDignore.symbol.file SaslGSS.java
- * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock SaslGSS
- */
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.RealmCallback;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslServer;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.ietf.jgss.*;
-import sun.security.jgss.GSSUtil;
-
-public class SaslGSS {
-
-    public static void main(String[] args) throws Exception {
-
-        String name = "host." + OneKDC.REALM.toLowerCase(Locale.US);
-
-        new OneKDC(null).writeJAASConf();
-        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
-
-        // Client in JGSS so that it can control wrap privacy mode
-        GSSManager m = GSSManager.getInstance();
-        GSSContext sc = m.createContext(
-                        m.createName(OneKDC.SERVER, GSSUtil.NT_GSS_KRB5_PRINCIPAL),
-                        GSSUtil.GSS_KRB5_MECH_OID,
-                        null,
-                        GSSContext.DEFAULT_LIFETIME);
-        sc.requestMutualAuth(false);
-
-        // Server in SASL
-        final HashMap props = new HashMap();
-        props.put(Sasl.QOP, "auth-conf");
-        SaslServer ss = Sasl.createSaslServer("GSSAPI", "server",
-                name, props,
-                new CallbackHandler() {
-                    public void handle(Callback[] callbacks)
-                            throws IOException, UnsupportedCallbackException {
-                        for (Callback cb : callbacks) {
-                            if (cb instanceof RealmCallback) {
-                                ((RealmCallback) cb).setText(OneKDC.REALM);
-                            } else if (cb instanceof AuthorizeCallback) {
-                                ((AuthorizeCallback) cb).setAuthorized(true);
-                            }
-                        }
-                    }
-                });
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        PrintStream oldErr = System.err;
-        System.setErr(new PrintStream(bout));
-
-        Logger.getLogger("javax.security.sasl").setLevel(Level.ALL);
-        Handler h = new ConsoleHandler();
-        h.setLevel(Level.ALL);
-        Logger.getLogger("javax.security.sasl").addHandler(h);
-
-        byte[] token = new byte[0];
-
-        try {
-            // Handshake
-            token = sc.initSecContext(token, 0, token.length);
-            token = ss.evaluateResponse(token);
-            token = sc.unwrap(token, 0, token.length, new MessageProp(0, false));
-            token[0] = (byte)(((token[0] & 4) != 0) ? 4 : 2);
-            token = sc.wrap(token, 0, token.length, new MessageProp(0, false));
-            ss.evaluateResponse(token);
-        } finally {
-            System.setErr(oldErr);
-        }
-
-        // Talk
-        // 1. Client sends a auth-int message
-        byte[] hello = "hello".getBytes();
-        MessageProp qop = new MessageProp(0, false);
-        token = sc.wrap(hello, 0, hello.length, qop);
-        // 2. Server accepts it anyway
-        ss.unwrap(token, 0, token.length);
-        // 3. Server sends a message
-        token = ss.wrap(hello, 0, hello.length);
-        // 4. Client accepts, should be auth-conf
-        sc.unwrap(token, 0, token.length, qop);
-        if (!qop.getPrivacy()) {
-            throw new Exception();
-        }
-
-        for (String s: bout.toString().split("\\n")) {
-            if (s.contains("KRB5SRV04") && s.contains("NULL")) {
-                return;
-            }
-        }
-        System.out.println("=======================");
-        System.out.println(bout.toString());
-        System.out.println("=======================");
-        throw new Exception("Haven't seen KRB5SRV04 with NULL");
-    }
-}
diff --git a/test/sun/security/krb5/config/Duration.java b/test/sun/security/krb5/config/Duration.java
new file mode 100644
index 0000000..d9c0f39
--- /dev/null
+++ b/test/sun/security/krb5/config/Duration.java
@@ -0,0 +1,71 @@
+/*
+ * 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 8044500
+ * @summary Add kinit options and krb5.conf flags that allow users to
+ *          obtain renewable tickets and specify ticket lifetimes
+ * @compile -XDignore.symbol.file Duration.java
+ * @run main Duration
+ */
+import sun.security.krb5.Config;
+import sun.security.krb5.KrbException;
+
+public class Duration {
+    public static void main(String[] args) throws Exception {
+        check("123", 123);
+        check("1:1", 3660);
+        check("1:1:1", 3661);
+        check("1d", 86400);
+        check("1h", 3600);
+        check("1h1m", 3660);
+        check("1h 1m", 3660);
+        check("1d 1h 1m 1s", 90061);
+        check("1d1h1m1s", 90061);
+
+        check("", -1);
+        check("abc", -1);
+        check("1ms", -1);
+        check("1d1d", -1);
+        check("1h1d", -1);
+        check("x1h", -1);
+        check("1h x 1m", -1);
+        check(":", -1);
+        check("1:60", -1);
+        check("1:1:1:1", -1);
+        check("1:1:1:", -1);
+    }
+
+    static void check(String s, int ex) throws Exception {
+        System.out.print("\u001b[1;37;41m" +s + " " + ex);
+        System.out.print("\u001b[m\n");
+        try {
+            int result = Config.duration(s);
+            if (result != ex) throw new Exception("for " + s + " is " + result);
+        } catch (KrbException ke) {
+            ke.printStackTrace();
+            if (ex != -1) throw new Exception();
+        }
+    }
+}
diff --git a/test/sun/security/lib/cacerts/VerifyCACerts.java b/test/sun/security/lib/cacerts/VerifyCACerts.java
index 585f1e9..bed497b 100644
--- a/test/sun/security/lib/cacerts/VerifyCACerts.java
+++ b/test/sun/security/lib/cacerts/VerifyCACerts.java
@@ -26,7 +26,7 @@
  * @test
  * @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779
  *      8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136
- *      8223499
+ *      8223499 8232019 8233223
  * @summary Check root CA entries in cacerts file
  */
 import java.io.File;
@@ -50,7 +50,7 @@
             + File.separator + "security" + File.separator + "cacerts";
 
     // The numbers of certs now.
-    private static final int COUNT = 88;
+    private static final int COUNT = 93;
 
     // map of cert alias to SHA-256 fingerprint
     @SuppressWarnings("serial")
@@ -233,6 +233,16 @@
                     "DD:69:36:FE:21:F8:F0:77:C1:23:A1:A5:21:C1:22:24:F7:22:55:B7:3E:03:A7:26:06:93:E8:A2:4B:0F:A3:89");
             put("globalsignrootcar6 [jdk]",
                     "2C:AB:EA:FE:37:D0:6C:A2:2A:BA:73:91:C0:03:3D:25:98:29:52:C4:53:64:73:49:76:3A:3A:B5:AD:6C:CF:69");
+            put("luxtrustglobalroot2ca [jdk]",
+                    "54:45:5F:71:29:C2:0B:14:47:C4:18:F9:97:16:8F:24:C5:8F:C5:02:3B:F5:DA:5B:E2:EB:6E:1D:D8:90:2E:D5");
+            put("amazonrootca1 [jdk]",
+                    "8E:CD:E6:88:4F:3D:87:B1:12:5B:A3:1A:C3:FC:B1:3D:70:16:DE:7F:57:CC:90:4F:E1:CB:97:C6:AE:98:19:6E");
+            put("amazonrootca2 [jdk]",
+                    "1B:A5:B2:AA:8C:65:40:1A:82:96:01:18:F8:0B:EC:4F:62:30:4D:83:CE:C4:71:3A:19:C3:9C:01:1E:A4:6D:B4");
+            put("amazonrootca3 [jdk]",
+                    "18:CE:6C:FE:7B:F1:4E:60:B2:E3:47:B8:DF:E8:68:CB:31:D0:2E:BB:3A:DA:27:15:69:F5:03:43:B4:6D:B3:A4");
+            put("amazonrootca4 [jdk]",
+                    "E3:5D:28:41:9E:D0:20:25:CF:A6:90:38:CD:62:39:62:45:8D:A5:C6:95:FB:DE:A3:C2:2B:0B:FB:25:89:70:92");
         }
     };
 
diff --git a/test/sun/security/pkcs12/MixedcaseAlias.java b/test/sun/security/pkcs12/MixedcaseAlias.java
new file mode 100644
index 0000000..520da00
--- /dev/null
+++ b/test/sun/security/pkcs12/MixedcaseAlias.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 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 8173956
+ * @summary KeyStore regression due to default keystore being changed to PKCS12
+ */
+
+import java.io.*;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+/**
+ * Test that a PKCS12 keystore entry with mixed-case alias can be retrieved.
+ */
+public class MixedcaseAlias {
+    private static final String DIR = System.getProperty("test.src", ".");
+    private static final String CERT = DIR + "/trusted.pem";
+    private static final String ALIAS = "Mixed-case Alias";
+
+    public static void main(String[] ignored) throws Exception {
+        KeyStore keystore = KeyStore.getInstance("PKCS12");
+        keystore.load(null, null);
+
+        keystore.setCertificateEntry(ALIAS, loadCertificate(CERT));
+        KeyStore.Entry entry = keystore.getEntry(ALIAS, null);
+
+        if (entry == null) {
+            throw new Exception(
+                "Error retrieving keystore entry using a mixed-case alias");
+        }
+
+        System.out.println("OK");
+    }
+
+    private static Certificate loadCertificate(String certFile)
+            throws Exception {
+        X509Certificate cert = null;
+        try (FileInputStream certStream = new FileInputStream(certFile)) {
+            CertificateFactory factory =
+                CertificateFactory.getInstance("X.509");
+            return factory.generateCertificate(certStream);
+        }
+    }
+}
diff --git a/test/sun/security/provider/DSA/TestAlgParameterGenerator.java b/test/sun/security/provider/DSA/TestAlgParameterGenerator.java
index 43ed0a9..385f1fb 100644
--- a/test/sun/security/provider/DSA/TestAlgParameterGenerator.java
+++ b/test/sun/security/provider/DSA/TestAlgParameterGenerator.java
@@ -23,56 +23,59 @@
 
 /*
  * @test
- * @bug 7044060 8181048
+ * @bug 7044060 8055351 8181048
  * @summary verify that DSA parameter generation works
- * @run main/othervm/timeout=300 TestAlgParameterGenerator
+ * @run main/timeout=600 TestAlgParameterGenerator
  */
-import java.security.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
+
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.spec.DSAGenParameterSpec;
+import java.security.spec.DSAParameterSpec;
 
 public class TestAlgParameterGenerator {
 
     private static void checkParamStrength(AlgorithmParameters param,
-                                           int strength) throws Exception {
+            int strength) throws Exception {
         String algo = param.getAlgorithm();
         if (!algo.equalsIgnoreCase("DSA")) {
-            throw new Exception("Unexpected type of parameters: " + algo);
+            throw new RuntimeException("Unexpected type of parameters: " + algo);
         }
         DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
         int valueL = spec.getP().bitLength();
         if (strength != valueL) {
             System.out.println("Expected " + strength + " but actual " + valueL);
-            throw new Exception("Wrong P strength");
+            throw new RuntimeException("Wrong P strength");
         }
     }
+
     private static void checkParamStrength(AlgorithmParameters param,
-                                           DSAGenParameterSpec genParam)
-        throws Exception {
+            DSAGenParameterSpec genParam)
+            throws Exception {
         String algo = param.getAlgorithm();
         if (!algo.equalsIgnoreCase("DSA")) {
-            throw new Exception("Unexpected type of parameters: " + algo);
+            throw new RuntimeException("Unexpected type of parameters: " + algo);
         }
         DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
         int valueL = spec.getP().bitLength();
         int strength = genParam.getPrimePLength();
         if (strength != valueL) {
             System.out.println("P: Expected " + strength + " but actual " + valueL);
-            throw new Exception("Wrong P strength");
+            throw new RuntimeException("Wrong P strength");
         }
         int valueN = spec.getQ().bitLength();
         strength = genParam.getSubprimeQLength();
         if (strength != valueN) {
             System.out.println("Q: Expected " + strength + " but actual " + valueN);
-            throw new Exception("Wrong Q strength");
+            throw new RuntimeException("Wrong Q strength");
         }
     }
 
     public static void main(String[] args) throws Exception {
-        AlgorithmParameterGenerator apg =
-            AlgorithmParameterGenerator.getInstance("DSA", "SUN");
-
+        AlgorithmParameterGenerator apg
+                = AlgorithmParameterGenerator.getInstance("DSA", "SUN");
         long start, stop;
+
         // make sure no-init still works
         start = System.currentTimeMillis();
         AlgorithmParameters param = apg.generateParameters();
@@ -80,9 +83,8 @@
         System.out.println("Time: " + (stop - start) + " ms.");
 
         // make sure the old model works
-        int[] strengths = { 512, 768, 1024 };
-        for (int i = 0; i < strengths.length; i++) {
-            int sizeP = strengths[i];
+        int[] strengths = {512, 768, 1024};
+        for (int sizeP : strengths) {
             System.out.println("Generating " + sizeP + "-bit DSA Parameters");
             start = System.currentTimeMillis();
             apg.init(sizeP);
@@ -93,18 +95,17 @@
         }
 
         // now the newer model
-        DSAGenParameterSpec spec1 = new DSAGenParameterSpec(1024, 160);
-        DSAGenParameterSpec spec2 = new DSAGenParameterSpec(2048, 224);
-        DSAGenParameterSpec spec3 = new DSAGenParameterSpec(2048, 256);
-        //DSAGenParameterSpec spec4 = new DSAGenParameterSpec(3072, 256);
         DSAGenParameterSpec[] specSet = {
-            spec1, spec2, spec3//, spec4
+            new DSAGenParameterSpec(1024, 160),
+            new DSAGenParameterSpec(2048, 224),
+            new DSAGenParameterSpec(2048, 256)
+            // no support for prime size 3072
+            // ,new DSAGenParameterSpec(3072, 256)
         };
-        for (int i = 0; i < specSet.length; i++) {
-            DSAGenParameterSpec genParam = specSet[i];
-            System.out.println("Generating (" + genParam.getPrimePLength() +
-                               ", " + genParam.getSubprimeQLength() +
-                               ") DSA Parameters");
+
+        for (DSAGenParameterSpec genParam : specSet) {
+            System.out.println("Generating (" + genParam.getPrimePLength()
+                    + ", " + genParam.getSubprimeQLength() + ") DSA Parameters");
             start = System.currentTimeMillis();
             apg.init(genParam, null);
             param = apg.generateParameters();
diff --git a/test/sun/security/provider/DSA/TestMaxLengthDER.java b/test/sun/security/provider/DSA/TestMaxLengthDER.java
new file mode 100644
index 0000000..a4f447c
--- /dev/null
+++ b/test/sun/security/provider/DSA/TestMaxLengthDER.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 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 8183591
+ * @summary Test decoding of DER length fields containing Integer.MAX_VALUE
+ * @run main TestMaxLengthDER
+ */
+
+import java.io.*;
+import java.math.*;
+import java.security.*;
+import java.security.spec.*;
+
+public class TestMaxLengthDER {
+
+    public static void main(String[] args) throws Exception {
+
+        String message = "Message";
+        Signature sig = Signature.getInstance("SHA256withDSA");
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
+        SecureRandom rnd = new SecureRandom();
+        rnd.setSeed(1);
+        kpg.initialize(2048, rnd);
+        KeyPair kp = kpg.generateKeyPair();
+        sig.initSign(kp.getPrivate());
+        sig.update(message.getBytes());
+        byte[] sigData = sig.sign();
+
+        // Set the length of the second integer to Integer.MAX_VALUE
+        // First copy all the signature data to the correct location
+        int lengthPos = sigData[3] + 5;
+        byte[] modifiedSigData = new byte[sigData.length + 4];
+        System.arraycopy(sigData, 0, modifiedSigData, 0, lengthPos);
+        System.arraycopy(sigData, lengthPos + 1, modifiedSigData,
+            lengthPos + 5, sigData.length - (lengthPos + 1));
+
+        // Increase the length (in bytes) of the sequence to account for
+        // the larger length field
+        modifiedSigData[1] += 4;
+
+        // Modify the length field
+        modifiedSigData[lengthPos] = (byte) 0x84;
+        modifiedSigData[lengthPos + 1] = (byte) 0x7F;
+        modifiedSigData[lengthPos + 2] = (byte) 0xFF;
+        modifiedSigData[lengthPos + 3] = (byte) 0xFF;
+        modifiedSigData[lengthPos + 4] = (byte) 0xFF;
+
+        sig.initVerify(kp.getPublic());
+        sig.update(message.getBytes());
+
+        try {
+            sig.verify(modifiedSigData);
+            throw new RuntimeException("No exception on misencoded signature");
+        } catch (SignatureException ex) {
+            if (ex.getCause() instanceof EOFException) {
+                // this is expected
+            } else {
+                throw ex;
+            }
+        }
+    }
+}
diff --git a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java
index 9fb21a2..389029c 100644
--- a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java
+++ b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,27 +21,31 @@
  * questions.
  */
 
-/*
- * This test is run using PostThruProxy.sh
- */
-
 import java.io.*;
 import java.net.*;
 import java.security.KeyStore;
 import javax.net.*;
 import javax.net.ssl.*;
-import java.security.cert.*;
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
 
 /*
- * This test case is written to test the https POST through a proxy.
- * There is no proxy authentication done.
- *
- * PostThruProxy.java -- includes a simple server that serves
- * http POST method requests in secure channel, and a client
- * that makes https POST request through a proxy.
+ * @test
+ * @bug 4423074
+ * @summary This test case is written to test the https POST through a proxy.
+ *          There is no proxy authentication done. It includes a simple server
+ *          that serves http POST method requests in secure channel, and a client
+ *          that makes https POST request through a proxy.
+ * @library /lib/testlibrary
+ * @compile OriginServer.java ProxyTunnelServer.java
+ * @run main/othervm PostThruProxy
  */
-
 public class PostThruProxy {
+
+    private static final String TEST_SRC = System.getProperty("test.src", ".");
+    private static final int TIMEOUT = 30000;
+
     /*
      * Where do we find the keystores?
      */
@@ -76,14 +80,10 @@
     /*
      * Main method to create the server and client
      */
-    public static void main(String args[]) throws Exception
-    {
-        String keyFilename =
-            args[1] + "/" + pathToStores +
-                "/" + keyStoreFile;
-        String trustFilename =
-           args[1] + "/" + pathToStores +
-                "/" + trustStoreFile;
+    public static void main(String args[]) throws Exception {
+        String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;
+        String trustFilename = TEST_SRC + "/" + pathToStores + "/"
+                + trustStoreFile;
 
         System.setProperty("javax.net.ssl.keyStore", keyFilename);
         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
@@ -95,10 +95,9 @@
          * setup the server
          */
         try {
-            ServerSocketFactory ssf =
-                PostThruProxy.getServerSocketFactory(useSSL);
+            ServerSocketFactory ssf = getServerSocketFactory(useSSL);
             ServerSocket ss = ssf.createServerSocket(serverPort);
-            ss.setSoTimeout(30000);  // 30 seconds
+            ss.setSoTimeout(TIMEOUT);  // 30 seconds
             serverPort = ss.getLocalPort();
             new TestServer(ss);
         } catch (Exception e) {
@@ -108,35 +107,29 @@
         }
         // trigger the client
         try {
-            doClientSide(args[0]);
+            doClientSide();
         } catch (Exception e) {
             System.out.println("Client side failed: " +
                                 e.getMessage());
             throw e;
-          }
+        }
     }
 
     private static ServerSocketFactory getServerSocketFactory
                    (boolean useSSL) throws Exception {
         if (useSSL) {
-            SSLServerSocketFactory ssf = null;
             // set up key manager to do server authentication
-            SSLContext ctx;
-            KeyManagerFactory kmf;
-            KeyStore ks;
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+            KeyStore ks = KeyStore.getInstance("JKS");
             char[] passphrase = passwd.toCharArray();
 
-            ctx = SSLContext.getInstance("TLS");
-            kmf = KeyManagerFactory.getInstance("SunX509");
-            ks = KeyStore.getInstance("JKS");
-
             ks.load(new FileInputStream(System.getProperty(
                         "javax.net.ssl.keyStore")), passphrase);
             kmf.init(ks, passphrase);
             ctx.init(kmf.getKeyManagers(), null, null);
 
-            ssf = ctx.getServerSocketFactory();
-            return ssf;
+            return ctx.getServerSocketFactory();
         } else {
             return ServerSocketFactory.getDefault();
         }
@@ -147,7 +140,7 @@
      */
     static String postMsg = "Testing HTTP post on a https server";
 
-    static void doClientSide(String hostname) throws Exception {
+    static void doClientSide() throws Exception {
         HostnameVerifier reservedHV =
             HttpsURLConnection.getDefaultHostnameVerifier();
         try {
@@ -162,10 +155,12 @@
              */
             HttpsURLConnection.setDefaultHostnameVerifier(
                                           new NameVerifier());
-            URL url = new URL("https://" + hostname+ ":" + serverPort);
+            URL url = new URL("https://" + getHostname() +":" + serverPort);
 
             Proxy p = new Proxy(Proxy.Type.HTTP, pAddr);
             HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p);
+            https.setConnectTimeout(TIMEOUT);
+            https.setReadTimeout(TIMEOUT);
             https.setDoOutput(true);
             https.setRequestMethod("POST");
             PrintStream ps = null;
@@ -190,6 +185,9 @@
                 if (ps != null)
                     ps.close();
                 throw e;
+            } catch (SocketTimeoutException e) {
+                System.out.println("Client can not get response in time: "
+                        + e.getMessage());
             }
         } finally {
             HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
@@ -210,4 +208,13 @@
         pserver.start();
         return new InetSocketAddress("localhost", pserver.getPort());
     }
+
+    private static String getHostname() {
+        try {
+            OutputAnalyzer oa = ProcessTools.executeCommand("hostname");
+            return oa.getOutput().trim();
+        } catch (Throwable e) {
+            throw new RuntimeException("Get hostname failed.", e);
+        }
+    }
 }
diff --git a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh
deleted file mode 100644
index 1b7cf98..0000000
--- a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-
-#
-# @test
-# @bug 4423074
-# @summary Need to rebase all the duplicated classes from Merlin
-
-HOSTNAME=`uname -n`
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin | AIX )
-    PS=":"
-    FS="/"
-    ;;
-  CYGWIN* )
-    PS=";"
-    FS="/"
-    ;;
-  Windows* )
-    PS=";"
-    FS="\\"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . \
-    ${TESTSRC}${FS}OriginServer.java \
-    ${TESTSRC}${FS}ProxyTunnelServer.java \
-    ${TESTSRC}${FS}PostThruProxy.java
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} PostThruProxy ${HOSTNAME} ${TESTSRC}
-exit
diff --git a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java
index ccd8360..15f8976 100644
--- a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java
+++ b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,28 +21,31 @@
  * questions.
  */
 
-/*
- * This test is run through PostThruProxyWithAuth.sh
- */
-
 import java.io.*;
 import java.net.*;
 import java.security.KeyStore;
 import javax.net.*;
 import javax.net.ssl.*;
-import java.security.cert.*;
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
 
 /*
- * This test case is written to test the https POST through a proxy
- * with proxy authentication.
- *
- * PostThruProxyWithAuth.java -- includes a simple server that serves
- * http POST method requests in secure channel, and a client
- * that makes https POST request through a proxy.
+ * @test
+ * @bug 4423074
+ * @summary This test case is written to test the https POST through a proxy
+ *          with proxy authentication. It includes a simple server that serves
+ *          http POST method requests in secure channel, and a client that
+ *          makes https POST request through a proxy.
+ * @library /lib/testlibrary
+ * @compile OriginServer.java ProxyTunnelServer.java
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth
  */
-
 public class PostThruProxyWithAuth {
 
+    private static final String TEST_SRC = System.getProperty("test.src", ".");
+    private static final int TIMEOUT = 30000;
+
     /*
      * Where do we find the keystores?
      */
@@ -78,14 +81,10 @@
     /*
      * Main method to create the server and client
      */
-    public static void main(String args[]) throws Exception
-    {
-        String keyFilename =
-            args[1] + "/" + pathToStores +
-                "/" + keyStoreFile;
-        String trustFilename =
-            args[1] + "/" + pathToStores +
-                "/" + trustStoreFile;
+    public static void main(String args[]) throws Exception {
+        String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;
+        String trustFilename = TEST_SRC + "/" + pathToStores + "/"
+                + trustStoreFile;
 
         System.setProperty("javax.net.ssl.keyStore", keyFilename);
         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
@@ -97,10 +96,9 @@
          * setup the server
          */
         try {
-            ServerSocketFactory ssf =
-                PostThruProxyWithAuth.getServerSocketFactory(useSSL);
+            ServerSocketFactory ssf = getServerSocketFactory(useSSL);
             ServerSocket ss = ssf.createServerSocket(serverPort);
-            ss.setSoTimeout(30000);  // 30 seconds
+            ss.setSoTimeout(TIMEOUT);  // 30 seconds
             serverPort = ss.getLocalPort();
             new TestServer(ss);
         } catch (Exception e) {
@@ -110,7 +108,7 @@
         }
         // trigger the client
         try {
-            doClientSide(args[0]);
+            doClientSide();
         } catch (Exception e) {
             System.out.println("Client side failed: " +
                                 e.getMessage());
@@ -121,24 +119,18 @@
     private static ServerSocketFactory getServerSocketFactory
                    (boolean useSSL) throws Exception {
         if (useSSL) {
-            SSLServerSocketFactory ssf = null;
             // set up key manager to do server authentication
-            SSLContext ctx;
-            KeyManagerFactory kmf;
-            KeyStore ks;
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+            KeyStore ks = KeyStore.getInstance("JKS");
             char[] passphrase = passwd.toCharArray();
 
-            ctx = SSLContext.getInstance("TLS");
-            kmf = KeyManagerFactory.getInstance("SunX509");
-            ks = KeyStore.getInstance("JKS");
-
             ks.load(new FileInputStream(System.getProperty(
                         "javax.net.ssl.keyStore")), passphrase);
             kmf.init(ks, passphrase);
             ctx.init(kmf.getKeyManagers(), null, null);
 
-            ssf = ctx.getServerSocketFactory();
-            return ssf;
+            return ctx.getServerSocketFactory();
         } else {
             return ServerSocketFactory.getDefault();
         }
@@ -149,7 +141,7 @@
      */
     static String postMsg = "Testing HTTP post on a https server";
 
-    static void doClientSide(String hostname) throws Exception {
+    static void doClientSide() throws Exception {
         /*
          * setup up a proxy
          */
@@ -161,10 +153,12 @@
          */
         HttpsURLConnection.setDefaultHostnameVerifier(
                                       new NameVerifier());
-        URL url = new URL("https://" + hostname + ":" + serverPort);
+        URL url = new URL("https://" + getHostname() + ":" + serverPort);
 
         Proxy p = new Proxy(Proxy.Type.HTTP, pAddr);
         HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p);
+        https.setConnectTimeout(TIMEOUT);
+        https.setReadTimeout(TIMEOUT);
         https.setDoOutput(true);
         https.setRequestMethod("POST");
         PrintStream ps = null;
@@ -188,6 +182,9 @@
             if (ps != null)
                 ps.close();
             throw e;
+        } catch (SocketTimeoutException e) {
+            System.out.println("Client can not get response in time: "
+                    + e.getMessage());
         }
     }
 
@@ -221,4 +218,13 @@
                                          "test123".toCharArray());
         }
     }
+
+    private static String getHostname() {
+        try {
+            OutputAnalyzer oa = ProcessTools.executeCommand("hostname");
+            return oa.getOutput().trim();
+        } catch (Throwable e) {
+            throw new RuntimeException("Get hostname failed.", e);
+        }
+    }
 }
diff --git a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh
deleted file mode 100644
index a89827c..0000000
--- a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-
-#
-# @test
-# @bug 4423074
-# @summary Need to rebase all the duplicated classes from Merlin
-
-HOSTNAME=`uname -n`
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin | AIX )
-    PS=":"
-    FS="/"
-    ;;
-  CYGWIN* )
-    PS=";"
-    FS="/"
-    ;;
-  Windows* )
-    PS=";"
-    FS="\\"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}${FS}OriginServer.java \
-    ${TESTSRC}${FS}ProxyTunnelServer.java \
-    ${TESTSRC}${FS}PostThruProxyWithAuth.java
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \
-    -Djdk.http.auth.tunneling.disabledSchemes= \
-    PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC}
-exit
diff --git a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java
index f498768..02a7af7 100644
--- a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java
+++ b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ProxyTunnelServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -32,13 +32,14 @@
 
 import java.io.*;
 import java.net.*;
-import javax.net.ssl.*;
 import javax.net.ServerSocketFactory;
 import sun.net.www.*;
 import java.util.Base64;
 
 public class ProxyTunnelServer extends Thread {
 
+    private static final int TIMEOUT = 30000;
+
     private static ServerSocket ss = null;
     /*
      * holds the registered user's username and password
@@ -64,8 +65,9 @@
 
     public ProxyTunnelServer() throws IOException {
         if (ss == null) {
-          ss = (ServerSocket) ServerSocketFactory.getDefault().
-          createServerSocket(0);
+            ss = (ServerSocket) ServerSocketFactory.getDefault()
+                    .createServerSocket(0);
+            ss.setSoTimeout(TIMEOUT);
         }
     }
 
@@ -86,6 +88,9 @@
         try {
             clientSocket = ss.accept();
             processRequests();
+        } catch (SocketTimeoutException e) {
+            System.out.println(
+                    "Proxy can not get response in time: " + e.getMessage());
         } catch (Exception e) {
             System.out.println("Proxy Failed: " + e);
             e.printStackTrace();
@@ -188,8 +193,8 @@
         serverToClient.start();
         System.out.println("Proxy: Started tunneling.......");
 
-        clientToServer.join();
-        serverToClient.join();
+        clientToServer.join(TIMEOUT);
+        serverToClient.join(TIMEOUT);
         System.out.println("Proxy: Finished tunneling........");
 
         clientToServer.close();
@@ -219,13 +224,11 @@
             int BUFFER_SIZE = 400;
             byte[] buf = new byte[BUFFER_SIZE];
             int bytesRead = 0;
-            int count = 0;  // keep track of the amount of data transfer
 
             try {
                 while ((bytesRead = input.read(buf)) >= 0) {
                     output.write(buf, 0, bytesRead);
                     output.flush();
-                    count += bytesRead;
                 }
             } catch (IOException e) {
                 /*
@@ -236,7 +239,7 @@
               }
         }
 
-        public void close() {
+        private void close() {
             try {
                 if (!sockIn.isClosed())
                     sockIn.close();
@@ -275,7 +278,7 @@
             serverPort = Integer.parseInt(connectInfo.substring(endi+1));
         } catch (Exception e) {
             throw new IOException("Proxy recieved a request: "
-                                        + connectStr);
+                                        + connectStr, e);
           }
         serverInetAddr = InetAddress.getByName(serverName);
     }
diff --git a/test/sun/security/tools/jarsigner/EntriesOrder.java b/test/sun/security/tools/jarsigner/EntriesOrder.java
index 96c90e9..908f6ef 100644
--- a/test/sun/security/tools/jarsigner/EntriesOrder.java
+++ b/test/sun/security/tools/jarsigner/EntriesOrder.java
@@ -25,6 +25,9 @@
  * @test
  * @bug 8031572
  * @summary jarsigner -verify exits with 0 when a jar file is not properly signed
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main EntriesOrder
  */
 
 import java.io.FileInputStream;
@@ -39,6 +42,8 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+import jdk.testlibrary.IOUtils;
+
 public class EntriesOrder {
 
     public static void main(String[] args) throws Exception {
@@ -106,7 +111,7 @@
                 Enumeration<JarEntry> jes = jf.entries();
                 while (jes.hasMoreElements()) {
                     JarEntry je = jes.nextElement();
-                    sun.misc.IOUtils.readFully(jf.getInputStream(je), -1, true);
+                    IOUtils.readFully(jf.getInputStream(je));
                     Certificate[] certs = je.getCertificates();
                     if (certs != null && certs.length > 0) {
                         cc++;
@@ -138,7 +143,7 @@
                 while (true) {
                     JarEntry je = jis.getNextJarEntry();
                     if (je == null) break;
-                    sun.misc.IOUtils.readFully(jis, -1, true);
+                    IOUtils.readFully(jis);
                     Certificate[] certs = je.getCertificates();
                     if (certs != null && certs.length > 0) {
                         cc++;
diff --git a/test/sun/security/tools/jarsigner/TimestampCheck.java b/test/sun/security/tools/jarsigner/TimestampCheck.java
index b5070ce..1018ace 100644
--- a/test/sun/security/tools/jarsigner/TimestampCheck.java
+++ b/test/sun/security/tools/jarsigner/TimestampCheck.java
@@ -743,7 +743,7 @@
         try (JarFile jf = new JarFile(file)) {
             JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA");
             try (InputStream is = jf.getInputStream(je)) {
-                byte[] content = IOUtils.readFully(is, -1, true);
+                byte[] content = IOUtils.readAllBytes(is);
                 PKCS7 p7 = new PKCS7(content);
                 SignerInfo[] si = p7.getSignerInfos();
                 if (si == null || si.length == 0) {
diff --git a/test/sun/security/tools/jarsigner/TsacertOptionTest.java b/test/sun/security/tools/jarsigner/TsacertOptionTest.java
index 96116e1..0bf70d3 100644
--- a/test/sun/security/tools/jarsigner/TsacertOptionTest.java
+++ b/test/sun/security/tools/jarsigner/TsacertOptionTest.java
@@ -87,6 +87,7 @@
                 "-storepass", PASSWORD,
                 "-keypass", PASSWORD,
                 "-dname", "CN=CA",
+                "-ext", "bc:c",
                 "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
         ProcessTools.executeCommand(KEYTOOL,
                 "-genkey",
diff --git a/test/sun/security/tools/jarsigner/Warning.java b/test/sun/security/tools/jarsigner/Warning.java
index 095d205..adb7833 100644
--- a/test/sun/security/tools/jarsigner/Warning.java
+++ b/test/sun/security/tools/jarsigner/Warning.java
@@ -42,7 +42,7 @@
 
         Files.deleteIfExists(Paths.get("ks"));
 
-        newCert("ca", "-validity 365000");
+        newCert("ca", "-validity 365000", "-ext bc:c");
 
         recreateJar();
 
diff --git a/test/sun/security/tools/jarsigner/concise_jarsigner.sh b/test/sun/security/tools/jarsigner/concise_jarsigner.sh
index b9ec9e8..b2affb4 100644
--- a/test/sun/security/tools/jarsigner/concise_jarsigner.sh
+++ b/test/sun/security/tools/jarsigner/concise_jarsigner.sh
@@ -22,7 +22,7 @@
 #
 
 # @test
-# @bug 6802846 8172529
+# @bug 6802846 8172529 8227758
 # @summary jarsigner needs enhanced cert validation(options)
 #
 # @run shell/timeout=240 concise_jarsigner.sh
@@ -207,15 +207,11 @@
 $JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
 [ $? = 0 ] || exit $LINENO
 
-# if ca2 is removed, -certchain still work because altchain is a self-signed entry and
-# it is trusted by jarsigner
+# if ca2 is removed and cert is imported, -certchain won't work because this certificate
+# entry is not trusted
 # save ca2.cert for easy replay
 $KT -exportcert -file ca2.cert -alias ca2
 $KT -delete -alias ca2
-$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
-[ $? = 0 ] || exit $LINENO
-
-# if cert is imported, -certchain won't work because this certificate entry is not trusted
 $KT -importcert -file certchain -alias altchain -noprompt
 $JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
 [ $? = 4 ] || exit $LINENO
@@ -228,8 +224,8 @@
 # ==========================================================
 
 $KT -genkeypair -alias ee -dname CN=ee
-$KT -genkeypair -alias caone -dname CN=caone
-$KT -genkeypair -alias catwo -dname CN=catwo
+$KT -genkeypair -alias caone -dname CN=caone -ext bc:c
+$KT -genkeypair -alias catwo -dname CN=catwo -ext bc:c
 
 $KT -certreq -alias ee | $KT -gencert -alias catwo -rfc > ee.cert
 $KT -certreq -alias catwo | $KT -gencert -alias caone -sigalg MD5withRSA -rfc > catwo.cert
diff --git a/test/sun/security/tools/jarsigner/ec.sh b/test/sun/security/tools/jarsigner/ec.sh
index 442e854..2893dca 100644
--- a/test/sun/security/tools/jarsigner/ec.sh
+++ b/test/sun/security/tools/jarsigner/ec.sh
@@ -53,7 +53,7 @@
 echo A > A
 $JAR cvf $JFILE A
 
-$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 || exit 11
+$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 -ext bc:c || exit 11
 
 $KT -alias a -dname CN=a -keyalg ec -genkey || exit 11
 $KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 111
diff --git a/test/sun/security/tools/jarsigner/onlymanifest.sh b/test/sun/security/tools/jarsigner/onlymanifest.sh
index bbc90a1..cc42e8f 100644
--- a/test/sun/security/tools/jarsigner/onlymanifest.sh
+++ b/test/sun/security/tools/jarsigner/onlymanifest.sh
@@ -57,7 +57,7 @@
 echo "Key: Value" > manifest
 $JAR cvfm $JFILE manifest
 
-$KT -alias ca -dname CN=ca -genkey -validity 300 || exit 1
+$KT -alias ca -dname CN=ca -genkey -validity 300 -ext bc:c || exit 1
 $KT -alias a -dname CN=a -genkey -validity 300 || exit 2
 $KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 3
 $JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 4
diff --git a/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java b/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java
index 1a49c15..bb0f448 100644
--- a/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -53,7 +53,7 @@
         // create a certificate whose signer certificate's
         // ExtendedKeyUsage extension doesn't allow code signing
         // create key pair for jar signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
diff --git a/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java b/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java
index fb0fac9..46cd564 100644
--- a/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -53,7 +53,7 @@
 
         // create a certificate whose signer certificate's KeyUsage extension
         // doesn't allow code signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
diff --git a/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java b/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java
index 443331d..0d1a063 100644
--- a/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -54,7 +54,7 @@
         // create a certificate whose signer certificate's
         // NetscapeCertType extension doesn't allow code signing
         // create key pair for jar signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
diff --git a/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java b/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java
index b9d0ae5..6055546 100644
--- a/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -54,7 +54,7 @@
         // Root CA is not checked at all. If the intermediate CA has
         // BasicConstraints extension set to true, it will be valid.
         // Otherwise, chain validation will fail.
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(CA2_KEY_ALIAS);
         issueCert(CA2_KEY_ALIAS,
                 "-ext",
diff --git a/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java b/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java
index f457776..1a8ee17 100644
--- a/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -52,7 +52,7 @@
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
         // create key pair for jar signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
diff --git a/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java b/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java
index 8a71c66..c414f48 100644
--- a/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -52,7 +52,7 @@
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
         // create key pair for jar signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
diff --git a/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java b/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java
index 078ff89..1aafc58 100644
--- a/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -51,7 +51,7 @@
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
         // create key pair for signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
         issueCert(
                 KEY_ALIAS,
diff --git a/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java b/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java
index 862e8ca..0831dc5 100644
--- a/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -54,7 +54,7 @@
         // create a jar file that contains one class file
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
 
         // create first expired certificate
         // whose ExtendedKeyUsage extension does not allow code signing
diff --git a/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java b/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java
index 8429fe2..447baab 100644
--- a/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -57,7 +57,7 @@
                 * 24 * 60 * 60 * 1000L);
 
         // create key pair
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
         issueCert(KEY_ALIAS,
                 "-validity", Integer.toString(VALIDITY));
diff --git a/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java b/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java
index 9fb9262..db415f9 100644
--- a/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -49,7 +49,7 @@
         Utils.createFiles(FIRST_FILE);
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
 
         // create first key pair for signing
         createAlias(FIRST_KEY_ALIAS);
diff --git a/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java b/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java
index 4d19c9a..a9aa77d 100644
--- a/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java
+++ b/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -50,7 +50,7 @@
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
         // create certificate that will be valid only tomorrow
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
diff --git a/test/sun/security/util/DerValue/BadValue.java b/test/sun/security/util/DerValue/BadValue.java
index ef3a9ef..d02a478 100644
--- a/test/sun/security/util/DerValue/BadValue.java
+++ b/test/sun/security/util/DerValue/BadValue.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -35,43 +35,48 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Test IOUtils.readFully
+        // Test IOUtils.
 
         // We have 4 bytes
         InputStream in = new ByteArrayInputStream(new byte[10]);
-        byte[] bs = IOUtils.readFully(in, 4, true);
+        byte[] bs = IOUtils.readExactlyNBytes(in, 4);
         if (bs.length != 4 || in.available() != 6) {
             throw new Exception("First read error");
         }
         // But only 6 left
-        bs = IOUtils.readFully(in, 10, false);
+        bs = IOUtils.readNBytes(in, 10);
         if (bs.length != 6 || in.available() != 0) {
             throw new Exception("Second read error");
         }
-        // MAX read as much as it can
+        // MAX length results in exception
         in = new ByteArrayInputStream(new byte[10]);
-        bs = IOUtils.readFully(in, Integer.MAX_VALUE, true);
-        if (bs.length != 10 || in.available() != 0) {
-            throw new Exception("Second read error");
+        try {
+            bs = IOUtils.readExactlyNBytes(in, Integer.MAX_VALUE);
+            throw new Exception("No exception on MAX_VALUE length");
+        } catch (EOFException ex) {
+            // this is expected
         }
-        // MAX ignore readAll
+        // -1 length results in exception
         in = new ByteArrayInputStream(new byte[10]);
-        bs = IOUtils.readFully(in, Integer.MAX_VALUE, false);
-        if (bs.length != 10 || in.available() != 0) {
-            throw new Exception("Second read error");
+        try {
+            bs = IOUtils.readExactlyNBytes(in, -1);
+            throw new Exception("No exception on -1 length");
+        } catch (IOException ex) {
+            // this is expected
         }
+
         // 20>10, readAll means failure
         in = new ByteArrayInputStream(new byte[10]);
         try {
-            bs = IOUtils.readFully(in, 20, true);
-            throw new Exception("Third read error");
+            bs = IOUtils.readExactlyNBytes(in, 20);
+            throw new Exception("No exception on EOF");
         } catch (EOFException e) {
             // OK
         }
         int bignum = 10 * 1024 * 1024;
-        bs = IOUtils.readFully(new SuperSlowStream(bignum), -1, true);
+        bs = IOUtils.readExactlyNBytes(new SuperSlowStream(bignum), bignum);
         if (bs.length != bignum) {
-            throw new Exception("Fourth read error");
+            throw new Exception("Read returned small array");
         }
 
         // Test DerValue
diff --git a/test/sun/security/validator/EndEntityExtensionCheck.java b/test/sun/security/validator/EndEntityExtensionCheck.java
index 3cff8fc..72db277 100644
--- a/test/sun/security/validator/EndEntityExtensionCheck.java
+++ b/test/sun/security/validator/EndEntityExtensionCheck.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -26,6 +26,7 @@
  * @bug 8076117
  * @summary EndEntityChecker should not process custom extensions
  *          after PKIX validation
+ * @run main/othervm -Djdk.security.allowNonCaAnchor EndEntityExtensionCheck
  */
 
 import java.io.ByteArrayInputStream;